Brought some styles into line
[moodle.git] / mod / forum / lib.php
CommitLineData
41905731 1<?php // $Id$
f93f848a 2
f1e0649c 3require_once($CFG->libdir.'/filelib.php');
7f6689e4 4
501cdbd8 5/// CONSTANTS ///////////////////////////////////////////////////////////
f93f848a 6
d3583b41 7define('FORUM_MODE_FLATOLDEST', 1);
8define('FORUM_MODE_FLATNEWEST', -1);
9define('FORUM_MODE_THREADED', 2);
10define('FORUM_MODE_NESTED', 3);
2e2e71a8 11
d3583b41 12define('FORUM_FORCESUBSCRIBE', 1);
13define('FORUM_INITIALSUBSCRIBE', 2);
709f0ec8 14
d3583b41 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
d3583b41 21$FORUM_TYPES = array ('general' => get_string('generalforum', 'forum'),
22 'eachuser' => get_string('eachuserforum', 'forum'),
23 'single' => get_string('singleforum', 'forum') );
f93f848a 24
d3583b41 25$FORUM_OPEN_MODES = array ('2' => get_string('openmode2', 'forum'),
26 '1' => get_string('openmode1', 'forum'),
27 '0' => get_string('openmode0', 'forum') );
70c476a7 28
5be7800c 29if (!isset($CFG->forum_displaymode)) {
d3583b41 30 set_config('forum_displaymode', FORUM_MODE_NESTED);
65b0e537 31}
73bb0835 32
5be7800c 33if (!isset($CFG->forum_shortpost)) {
d3583b41 34 set_config('forum_shortpost', 300); // Less non-HTML characters than this is short
65b0e537 35}
4d871a72 36
5be7800c 37if (!isset($CFG->forum_longpost)) {
d3583b41 38 set_config('forum_longpost', 600); // More non-HTML characters than this is long
65b0e537 39}
4d871a72 40
5be7800c 41if (!isset($CFG->forum_manydiscussions)) {
d3583b41 42 set_config('forum_manydiscussions', 100); // Number of discussions on a page
65b0e537 43}
e07635f4 44
4909e176 45if (!isset($CFG->forum_maxbytes)) {
d3583b41 46 set_config('forum_maxbytes', 512000); // Default maximum size for all forums
65b0e537 47}
4909e176 48
f37da850 49if (!isset($CFG->forum_trackreadposts)) {
d3583b41 50 set_config('forum_trackreadposts', true); // Default whether user needs to mark a post as read
f37da850 51}
52
53if (!isset($CFG->forum_oldpostdays)) {
baa2f74e 54 set_config('forum_oldpostdays', 30); // Default number of days that a post is considered old
f37da850 55}
56
57if (!isset($CFG->forum_usermarksread)) {
d3583b41 58 set_config('forum_usermarksread', false); // Default whether user needs to mark a post as read
f37da850 59}
60
61if (!isset($CFG->forum_cleanreadtime)) {
d3583b41 62 set_config('forum_cleanreadtime', 2); // Default time (hour) to execute 'clean_read_records' cron
f37da850 63}
64
1246ea56 65if (!isset($CFG->forum_replytouser)) {
d3583b41 66 set_config('forum_replytouser', true); // Default maximum size for all forums
1246ea56 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
d3583b41 100 if (! $forum->id = insert_record('forum', $forum)) {
cb9a975f 101 return false;
102 }
103
d3583b41 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)) {
d3583b41 112 error('Could not add the discussion for this forum');
caadf009 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
d3583b41 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');
caadf009 153 $discussion = array_pop($discussions);
154 } else {
d3583b41 155 error('Could not find the discussion in this forum');
caadf009 156 }
157 }
d3583b41 158 if (! $post = get_record('forum_posts', 'id', $discussion->firstpost)) {
159 error('Could not find the first post in this forum discussion');
caadf009 160 }
161
162 $post->subject = $forum->name;
163 $post->message = $forum->intro;
164 $post->modified = $forum->timemodified;
165
d3583b41 166 if (! update_record('forum_posts', $post)) {
167 error('Could not update the first post');
caadf009 168 }
169
170 $discussion->name = $forum->name;
171
d3583b41 172 if (! update_record('forum_discussions', $discussion)) {
173 error('Could not update the discussion');
caadf009 174 }
175 }
176
d3583b41 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
d3583b41 186 if (! $forum = get_record('forum', 'id', $id)) {
caadf009 187 return false;
188 }
189
190 $result = true;
191
d3583b41 192 if ($discussions = get_records('forum_discussions', 'forum', $forum->id)) {
caadf009 193 foreach ($discussions as $discussion) {
194 if (! forum_delete_discussion($discussion)) {
195 $result = false;
196 }
197 }
198 }
199
d3583b41 200 if (! delete_records('forum_subscriptions', 'forum', $forum->id)) {
caadf009 201 $result = false;
202 }
203
f37da850 204 forum_tp_delete_read_records(-1, -1, -1, $forum->id);
205
d3583b41 206 if (! delete_records('forum', 'id', $forum->id)) {
caadf009 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)) {
d3583b41 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
d3583b41 258 mtrace(get_string('processingpost', 'forum', $post->id), '');
caadf009 259
d3583b41 260 if (! $userfrom = get_record('user', 'id', $post->userid)) {
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++;
e3ff14ca 562
f37da850 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) {
e3ff14ca 714
f37da850 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
95e72c12 886 $st_subscriptions = get_records_sql("SELECT DISTINCT u.id, u.id
05855091 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
95e72c12 892 $st_posts = get_records_sql("SELECT DISTINCT u.id, u.id
05855091 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
95e72c12 901 $st_ratings = get_records_sql("SELECT DISTINCT u.id, u.id
05855091 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
c7a5b3b1 979function forum_search_posts($searchterms, $courseid, $page=0, $recordsperpage=50, &$totalcount, $groupid=0) {
8b9c7aa0 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');
e3ff14ca 986
9fa49e22 987 if (!isteacher($courseid)) {
988 $notteacherforum = "AND f.type <> 'teacher'";
4cabd355 989 $forummodule = get_record("modules", "name", "forum");
990 $onlyvisible = " AND f.id = cm.instance AND cm.visible = 1 AND cm.module = $forummodule->id";
991 $onlyvisibletable = ", {$CFG->prefix}course_modules cm";
c7a5b3b1 992 if ($groupid) {
993 $separategroups = SEPARATEGROUPS;
994 $selectgroup = " AND (cm.groupmode <> '$separategroups' OR d.groupid = '$groupid')";
995 } else {
996 $selectgroup = '';
997 }
9fa49e22 998 } else {
999 $notteacherforum = "";
c7a5b3b1 1000 $selectgroup = '';
4cabd355 1001 $onlyvisible = "";
1002 $onlyvisibletable = "";
9fa49e22 1003 }
1004
e6ae4dc8 1005 $limit = sql_paging_limit($page, $recordsperpage);
97485d07 1006
63d99fcb 1007 /// Some differences in syntax for PostgreSQL
1008 if ($CFG->dbtype == "postgres7") {
a74f950c 1009 $LIKE = "ILIKE"; // case-insensitive
2b4c64e9 1010 $NOTLIKE = "NOT ILIKE"; // case-insensitive
1011 $REGEXP = "~*";
1012 $NOTREGEXP = "!~*";
b800ac5a 1013 } else {
a74f950c 1014 $LIKE = "LIKE";
2b4c64e9 1015 $NOTLIKE = "NOT LIKE";
a74f950c 1016 $REGEXP = "REGEXP";
2b4c64e9 1017 $NOTREGEXP = "NOT REGEXP";
c4c57597 1018 }
1019
b800ac5a 1020 $messagesearch = "";
855c0839 1021 $searchstring = "";
1022 // Need to concat these back together for parser to work.
1023 foreach($searchterms as $searchterm){
1024 if ($searchstring != "") {
1025 $searchstring .= " ";
63d99fcb 1026 }
855c0839 1027 $searchstring .= $searchterm;
b800ac5a 1028 }
1029
855c0839 1030 // We need to allow quoted strings for the search. The quotes *should* be stripped
1031 // by the parser, but this should be examined carefully for security implications.
1032 $searchstring = str_replace("\\\"","\"",$searchstring);
1033 $parser = new search_parser();
f99fcffe 1034 $lexer = new search_lexer($parser);
e6ae4dc8 1035
855c0839 1036 if ($lexer->parse($searchstring)) {
1037 $parsearray = $parser->get_parsed_array();
77ffdf4b 1038 $messagesearch = search_generate_SQL($parsearray,'p.message','p.subject','p.userid','u.id','u.firstname','u.lastname','p.modified', 'd.forum');
855c0839 1039 }
e3ff14ca 1040
65b0e537 1041 $selectsql = "{$CFG->prefix}forum_posts p,
1042 {$CFG->prefix}forum_discussions d,
1043 {$CFG->prefix}user u,
4cabd355 1044 {$CFG->prefix}forum f $onlyvisibletable
855c0839 1045 WHERE ($messagesearch)
65b0e537 1046 AND p.userid = u.id
1047 AND p.discussion = d.id
1048 AND d.course = '$courseid'
c7a5b3b1 1049 AND d.forum = f.id $notteacherforum $onlyvisible $selectgroup";
65b0e537 1050
8b9c7aa0 1051 $totalcount = count_records_sql("SELECT COUNT(*) FROM $selectsql");
b800ac5a 1052
8b9c7aa0 1053 return get_records_sql("SELECT p.*,u.firstname,u.lastname,u.email,u.picture FROM
1054 $selectsql ORDER BY p.modified DESC $limit");
9fa49e22 1055}
1056
63d99fcb 1057
9fa49e22 1058function forum_get_ratings($postid, $sort="u.firstname ASC") {
1059/// Returns a list of ratings for a particular post - sorted.
1060 global $CFG;
65b0e537 1061 return get_records_sql("SELECT u.*, r.rating, r.time
1062 FROM {$CFG->prefix}forum_ratings r,
9fa49e22 1063 {$CFG->prefix}user u
65b0e537 1064 WHERE r.post = '$postid'
1065 AND r.userid = u.id
9fa49e22 1066 ORDER BY $sort");
1067}
1068
3ecca1ee 1069function forum_get_unmailed_posts($starttime, $endtime) {
1f48942e 1070/// Returns a list of all new posts that have not been mailed yet
1071 global $CFG;
65b0e537 1072 return get_records_sql("SELECT p.*, d.course
1073 FROM {$CFG->prefix}forum_posts p,
1f48942e 1074 {$CFG->prefix}forum_discussions d
65b0e537 1075 WHERE p.mailed = 0
3ecca1ee 1076 AND p.created >= '$starttime'
1077 AND p.created < '$endtime'
c274b0e0 1078 AND p.discussion = d.id
1079 ORDER BY p.modified ASC");
1f48942e 1080}
1081
3ecca1ee 1082function forum_mark_old_posts_as_mailed($endtime) {
1083/// Marks posts before a certain time as being mailed already
1084 global $CFG;
c274b0e0 1085 return execute_sql("UPDATE {$CFG->prefix}forum_posts
1086 SET mailed = '1'
1087 WHERE created < '$endtime'");
3ecca1ee 1088}
1089
1f48942e 1090function forum_get_user_posts($forumid, $userid) {
1091/// Get all the posts for a user in a forum suitable for forum_print_post
1092 global $CFG;
1093
ebc3bd2b 1094 return get_records_sql("SELECT p.*, u.firstname, u.lastname, u.email, u.picture
65b0e537 1095 FROM {$CFG->prefix}forum f,
1096 {$CFG->prefix}forum_discussions d,
1097 {$CFG->prefix}forum_posts p,
1098 {$CFG->prefix}user u
1099 WHERE f.id = '$forumid'
1100 AND d.forum = f.id
1f48942e 1101 AND p.discussion = d.id
65b0e537 1102 AND p.userid = '$userid'
ebc3bd2b 1103 AND p.userid = u.id
1f48942e 1104 ORDER BY p.modified ASC");
1105}
1106
1107function forum_get_post_from_log($log) {
1108/// Given a log entry, return the forum post details for it.
1109 global $CFG;
1110
1111 if ($log->action == "add post") {
1112
2f9c977e 1113 return get_record_sql("SELECT p.*, d.forum, d.groupid, u.firstname, u.lastname, u.email, u.picture
65b0e537 1114 FROM {$CFG->prefix}forum_discussions d,
1115 {$CFG->prefix}forum_posts p,
1116 {$CFG->prefix}user u
1117 WHERE p.id = '$log->info'
1118 AND d.id = p.discussion
1119 AND p.userid = u.id
1f48942e 1120 AND u.deleted <> '1'");
1121
1122
1123 } else if ($log->action == "add discussion") {
1124
2f9c977e 1125 return get_record_sql("SELECT p.*, d.forum, d.groupid, u.firstname, u.lastname, u.email, u.picture
65b0e537 1126 FROM {$CFG->prefix}forum_discussions d,
1127 {$CFG->prefix}forum_posts p,
1128 {$CFG->prefix}user u
1129 WHERE d.id = '$log->info'
1130 AND d.firstpost = p.id
1131 AND p.userid = u.id
1f48942e 1132 AND u.deleted <> '1'");
1133 }
1134 return NULL;
1135}
1136
d05956ac 1137function forum_get_firstpost_from_discussion($discussionid) {
1138/// Given a discussion id, return the first post from the discussion
1139 global $CFG;
1140
1141 return get_record_sql("SELECT p.*
65b0e537 1142 FROM {$CFG->prefix}forum_discussions d,
d05956ac 1143 {$CFG->prefix}forum_posts p
65b0e537 1144 WHERE d.id = '$discussionid'
d05956ac 1145 AND d.firstpost = p.id ");
1146}
1147
1f48942e 1148
1149function forum_get_user_grades($forumid) {
1150/// Get all user grades for a forum
1151 global $CFG;
1152
ebc3bd2b 1153 return get_records_sql("SELECT r.id, p.userid, r.rating
65b0e537 1154 FROM {$CFG->prefix}forum_discussions d,
1155 {$CFG->prefix}forum_posts p,
1f48942e 1156 {$CFG->prefix}forum_ratings r
65b0e537 1157 WHERE d.forum = '$forumid'
1f48942e 1158 AND p.discussion = d.id
02ebf404 1159 AND r.post = p.id
1160 ORDER by p.userid ");
1f48942e 1161}
1162
1163
a48e8c4b 1164function forum_count_discussion_replies($forum='0', $course='0', $user='0') {
1165// Returns an array of counts of replies to each discussion (optionally in one forum or course and/or user)
1f48942e 1166 global $CFG;
1167
a48e8c4b 1168 $forumselect = $courseselect = $userselect = '';
1169
1f48942e 1170 if ($forum) {
1171 $forumselect = " AND d.forum = '$forum'";
a48e8c4b 1172 }
1173 if ($course) {
1174 $courseselect = " AND d.course = '$course'";
1175 }
1176 if ($user) {
1177 $userselect = " AND d.userid = '$user'";
1f48942e 1178 }
3599e487 1179 return get_records_sql("SELECT p.discussion, (count(*)) as replies, max(p.id) as lastpostid
65b0e537 1180 FROM {$CFG->prefix}forum_posts p,
1f48942e 1181 {$CFG->prefix}forum_discussions d
a48e8c4b 1182 WHERE p.parent > 0 $forumselect $courseselect $userselect
1c887009 1183 AND p.discussion = d.id
1f48942e 1184 GROUP BY p.discussion");
1185}
1186
1187function forum_count_unrated_posts($discussionid, $userid) {
1188// How many unrated posts are in the given discussion for a given user?
1189 global $CFG;
1190 if ($posts = get_record_sql("SELECT count(*) as num
1191 FROM {$CFG->prefix}forum_posts
65b0e537 1192 WHERE parent > 0
1193 AND discussion = '$discussionid'
ebc3bd2b 1194 AND userid <> '$userid' ")) {
1f48942e 1195
65b0e537 1196 if ($rated = get_record_sql("SELECT count(*) as num
1197 FROM {$CFG->prefix}forum_posts p,
1f48942e 1198 {$CFG->prefix}forum_ratings r
1199 WHERE p.discussion = '$discussionid'
65b0e537 1200 AND p.id = r.post
ebc3bd2b 1201 AND r.userid = '$userid'")) {
1f48942e 1202 $difference = $posts->num - $rated->num;
1203 if ($difference > 0) {
1204 return $difference;
1205 } else {
1206 return 0; // Just in case there was a counting error
1207 }
1208 } else {
1209 return $posts->num;
1210 }
1211 } else {
1212 return 0;
1213 }
1214}
1215
65b0e537 1216function forum_get_discussions($forum="0", $forumsort="d.timemodified DESC",
90ec387a 1217 $user=0, $fullpost=true, $visiblegroups=-1, $limit=0) {
1f48942e 1218/// Get all discussions in a forum
1219 global $CFG;
1220
1221 if ($user) {
1222 $userselect = " AND u.id = '$user' ";
1223 } else {
1224 $userselect = "";
1225 }
2862b309 1226
90ec387a 1227 if ($limit) {
1228 $limit = " LIMIT $limit ";
1229 } else {
1230 $limit = "";
1231 }
8f0cd6ef 1232
2862b309 1233 if ($visiblegroups == -1) {
02509fe6 1234 $groupselect = "";
2862b309 1235 } else {
1236 $groupselect = " AND (d.groupid = '$visiblegroups' OR d.groupid = '-1') ";
02509fe6 1237 }
2862b309 1238
29507631 1239 if (empty($forumsort)) {
1240 $forumsort = "d.timemodified DESC";
1241 }
2ab968e9 1242 if (empty($fullpost)) {
b879effb 1243 $postdata = "p.id,p.subject,p.modified,p.discussion,p.userid";
2ab968e9 1244 } else {
1245 $postdata = "p.*";
1246 }
9197e147 1247
3a68fbbb 1248 return get_records_sql("SELECT $postdata, d.name, d.timemodified, d.usermodified, d.groupid,
e3ff14ca 1249 u.firstname, u.lastname, u.email, u.picture,
268c6485 1250 um.firstname AS umfirstname, um.lastname AS umlastname
65b0e537 1251 FROM {$CFG->prefix}forum_discussions d,
9197e147 1252 {$CFG->prefix}forum_posts p,
268c6485 1253 {$CFG->prefix}user um,
65b0e537 1254 {$CFG->prefix}user u
1255 WHERE d.forum = '$forum'
1256 AND p.discussion = d.id
1257 AND p.parent = 0
9197e147 1258 AND p.userid = u.id $groupselect $userselect
e3ff14ca 1259 AND (d.usermodified = um.id OR d.usermodified = 0)
90ec387a 1260 ORDER BY $forumsort $limit");
1f48942e 1261}
1262
1263
1264
b656e2a9 1265function forum_get_user_discussions($courseid, $userid, $groupid=0) {
1266/// Get all discussions started by a particular user in a course (or group)
1f48942e 1267 global $CFG;
1268
b656e2a9 1269 if ($groupid) {
1270 $groupselect = " AND d.groupid = '$groupid' ";
1271 } else {
1272 $groupselect = "";
1273 }
1274
2862b309 1275 return get_records_sql("SELECT p.*, d.groupid, u.firstname, u.lastname, u.email, u.picture,
ebc3bd2b 1276 f.type as forumtype, f.name as forumname, f.id as forumid
65b0e537 1277 FROM {$CFG->prefix}forum_discussions d,
1278 {$CFG->prefix}forum_posts p,
1279 {$CFG->prefix}user u,
1f48942e 1280 {$CFG->prefix}forum f
65b0e537 1281 WHERE d.course = '$courseid'
1282 AND p.discussion = d.id
1283 AND p.parent = 0
1284 AND p.userid = u.id
1285 AND u.id = '$userid'
b656e2a9 1286 AND d.forum = f.id $groupselect
b8bf90c5 1287 ORDER BY p.created DESC");
1f48942e 1288}
1289
1290
6673d7bd 1291function forum_subscribed_users($course, $forum, $groupid=0) {
1f48942e 1292/// Returns list of user objects that are subscribed to this forum
1293 global $CFG;
1294
6673d7bd 1295 if ($groupid) {
1296 $grouptables = ", {$CFG->prefix}groups_members g";
1297 $groupselect = " AND g.groupid = '$groupid' AND u.id = g.userid";
1298 } else {
1299 $grouptables = "";
1300 $groupselect = "";
1301 }
1302
709f0ec8 1303 if (forum_is_forcesubscribed($forum->id)) {
7b5944cd 1304 if ($forum->type == "teacher") {
1305 return get_course_teachers($course->id); // Only teachers can be subscribed to teacher forums
adaf3928 1306 } else {
7b5944cd 1307 return get_course_users($course->id); // Otherwise get everyone in the course
1f48942e 1308 }
1309 }
aaf7a9dc 1310 return get_records_sql("SELECT u.id, u.username, u.firstname, u.lastname, u.maildisplay, u.mailformat, u.maildigest, u.emailstop,
0351b1f9 1311 u.email, u.city, u.country, u.lastaccess, u.lastlogin, u.picture, u.timezone, u.lang
65b0e537 1312 FROM {$CFG->prefix}user u,
6673d7bd 1313 {$CFG->prefix}forum_subscriptions s $grouptables
1f48942e 1314 WHERE s.forum = '$forum->id'
65b0e537 1315 AND s.userid = u.id
6673d7bd 1316 AND u.deleted <> 1 $groupselect
7c81b6e2 1317 ORDER BY u.email ASC");
1f48942e 1318}
9fa49e22 1319
067675c0 1320
1321
caadf009 1322/// OTHER FUNCTIONS ///////////////////////////////////////////////////////////
f93f848a 1323
1324
11b0c469 1325function forum_get_course_forum($courseid, $type) {
1326// How to set up special 1-per-course forums
a6fcdf98 1327 global $CFG;
1328
29cbd93a 1329 if ($forums = get_records_select("forum", "course = '$courseid' AND type = '$type'", "id ASC")) {
65b0e537 1330 // There should always only be ONE, but with the right combination of
29cbd93a 1331 // errors there might be more. In this case, just return the oldest one (lowest ID).
1332 foreach ($forums as $forum) {
1333 return $forum; // ie the first one
11b0c469 1334 }
8daaf761 1335 }
e6874d9f 1336
8daaf761 1337 // Doesn't exist, so create one now.
1338 $forum->course = $courseid;
1339 $forum->type = "$type";
1340 switch ($forum->type) {
1341 case "news":
65a3ef30 1342 $forum->name = addslashes(get_string("namenews", "forum"));
1343 $forum->intro = addslashes(get_string("intronews", "forum"));
906fef94 1344 $forum->forcesubscribe = FORUM_FORCESUBSCRIBE;
8daaf761 1345 $forum->open = 1; // 0 - no, 1 - posts only, 2 - discuss and post
1346 $forum->assessed = 0;
709f0ec8 1347 if ($courseid == SITEID) {
1348 $forum->name = get_string("sitenews");
1349 $forum->forcesubscribe = 0;
8f0cd6ef 1350 }
8daaf761 1351 break;
1352 case "social":
65a3ef30 1353 $forum->name = addslashes(get_string("namesocial", "forum"));
1354 $forum->intro = addslashes(get_string("introsocial", "forum"));
8daaf761 1355 $forum->open = 2; // 0 - no, 1 - posts only, 2 - discuss and post
1356 $forum->assessed = 0;
1357 $forum->forcesubscribe = 0;
1358 break;
1359 case "teacher":
65a3ef30 1360 $forum->name = addslashes(get_string("nameteacher", "forum"));
1361 $forum->intro = addslashes(get_string("introteacher", "forum"));
a796d0b8 1362 $forum->open = 2; // 0 - no, 1 - posts only, 2 - discuss and post
8daaf761 1363 $forum->assessed = 0;
1364 $forum->forcesubscribe = 0;
1365 break;
1366 default:
1367 notify("That forum type doesn't exist!");
1368 return false;
1369 break;
1370 }
1371
1372 $forum->timemodified = time();
1373 $forum->id = insert_record("forum", $forum);
1374
1375 if ($forum->type != "teacher") {
1376 if (! $module = get_record("modules", "name", "forum")) {
1377 notify("Could not find forum module!!");
1378 return false;
1379 }
1380 $mod->course = $courseid;
1381 $mod->module = $module->id;
1382 $mod->instance = $forum->id;
1383 $mod->section = 0;
1384 if (! $mod->coursemodule = add_course_module($mod) ) { // assumes course/lib.php is loaded
1385 notify("Could not add a new course module to the course '$course->fullname'");
1386 return false;
1387 }
1388 if (! $sectionid = add_mod_to_section($mod) ) { // assumes course/lib.php is loaded
1389 notify("Could not add the new course module to that section");
1390 return false;
1391 }
1392 if (! set_field("course_modules", "section", $sectionid, "id", $mod->coursemodule)) {
1393 notify("Could not update the course module with the correct section");
1394 return false;
1395 }
1396 include_once("$CFG->dirroot/course/lib.php");
d769d2ee 1397 rebuild_course_cache($courseid);
82aa0e8d 1398 }
65b0e537 1399
8daaf761 1400 return get_record("forum", "id", "$forum->id");
82aa0e8d 1401}
1402
f93f848a 1403
65b0e537 1404function forum_make_mail_post(&$post, $user, $touser, $course,
11b0c469 1405 $ownpost=false, $reply=false, $link=false, $rate=false, $footer="") {
65b0e537 1406// Given the data about a posting, builds up the HTML to display it and
501cdbd8 1407// returns the HTML in a string. This is designed for sending via HTML email.
1408
d30867b0 1409 global $CFG;
501cdbd8 1410
0d851f90 1411 static $formattedtext; // Cached version of formatted text for a post
1412 static $formattedtextid; // The ID number of the post
1413
1414 if (empty($formattedtextid) or $formattedtextid != $post->id) { // Recalculate the formatting
1415 $formattedtext = format_text($post->message, $post->format, NULL, $course->id);
1416 $formattedtextid = $post->id;
1417 }
1418
501cdbd8 1419 $output = "";
1420
9c674431 1421 $output .= '<table border="0" cellpadding="3" cellspacing="0" class="forumpost">';
501cdbd8 1422
d30867b0 1423 $output .= "<tr><td width=\"35\" valign=\"top\" class=\"forumpostpicture\">";
501cdbd8 1424 $output .= print_user_picture($user->id, $course->id, $user->picture, false, true);
72d497d4 1425 $output .= "</td>";
501cdbd8 1426
1427 if ($post->parent) {
d30867b0 1428 $output .= "<td nowrap=\"nowrap\" class=\"forumpostheader\">";
501cdbd8 1429 } else {
d30867b0 1430 $output .= "<td nowrap=\"nowrap\" class=\"forumpostheadertopic\">";
501cdbd8 1431 }
72d497d4 1432 $output .= "<p>";
41905731 1433 $output .= "<font size=\"3\"><b>$post->subject</b></font><br />";
1434 $output .= "<font size=\"2\">";
1b26d5e7 1435
1436 $fullname = fullname($user, isteacher($course->id));
839f2456 1437 $by->name = "<a href=\"$CFG->wwwroot/user/view.php?id=$user->id&amp;course=$course->id\">$fullname</a>";
d62413e8 1438 $by->date = userdate($post->modified, "", $touser->timezone);
ffe11640 1439 $output .= get_string("bynameondate", "forum", $by);
1b26d5e7 1440
72d497d4 1441 $output .= "</font></p></td></tr>";
d30867b0 1442 $output .= "<tr><td width=\"10\" class=\"forumpostside\">";
501cdbd8 1443 $output .= "&nbsp;";
d30867b0 1444 $output .= "</td><td class=\"forumpostmessage\">\n";
501cdbd8 1445
7f6689e4 1446 if ($post->attachment) {
1447 $post->course = $course->id;
1448 $post->forum = get_field("forum_discussions", "forum", "id", $post->discussion);
41905731 1449 $output .= "<div align=\"right\">";
7f6689e4 1450 $output .= forum_print_attachments($post, "html");
72d497d4 1451 $output .= "</div>";
7f6689e4 1452 }
1453
0d851f90 1454 $output .= $formattedtext;
501cdbd8 1455
839f2456 1456 $output .= "<p align=\"right\"><font size=\"-1\">";
501cdbd8 1457
2e2e71a8 1458 if ($post->parent) {
839f2456 1459 $output .= "<a href=\"$CFG->wwwroot/mod/forum/discuss.php?d=$post->discussion&amp;parent=$post->parent\">".get_string("parent", "forum")."</a> | ";
2e2e71a8 1460 }
ce45515e 1461
501cdbd8 1462 $age = time() - $post->created;
1463 if ($ownpost) {
14eef464 1464 $output .= "<a href=\"$CFG->wwwroot/mod/forum/post.php?delete=$post->id\">".get_string("delete", "forum")."</a>";
501cdbd8 1465 if ($reply) {
cf84431b 1466 $output .= "<a target=\"_blank\" href=\"$CFG->wwwroot/mod/forum/post.php?reply=$post->id\">".get_string("replyforum", "forum")."</a>";
501cdbd8 1467 }
1468 $output .= "&nbsp;&nbsp;";
1469 } else {
1470 if ($reply) {
02509fe6 1471 $output .= "<a target=\"_blank\" href=\"$CFG->wwwroot/mod/forum/post.php?reply=$post->id\">".get_string("replyforum", "forum")."</a>&nbsp;&nbsp;";
501cdbd8 1472 }
1473 }
1474
72d497d4 1475 $output .= "</p>";
41905731 1476 $output .= "<div align=\"right\"><p align=\"right\">";
65b0e537 1477
501cdbd8 1478 if ($link) {
1479 if ($post->replies == 1) {
ffe11640 1480 $replystring = get_string("repliesone", "forum", $post->replies);
501cdbd8 1481 } else {
ffe11640 1482 $replystring = get_string("repliesmany", "forum", $post->replies);
501cdbd8 1483 }
41905731 1484 $output .= "<a href=\"$CFG->wwwroot/mod/forum/discuss.php?d=$post->discussion\"><b>".get_string("discussthistopic", "forum")."</b></a> ($replystring)&nbsp;&nbsp;";
501cdbd8 1485 }
72d497d4 1486 $output .= "</p></div>";
501cdbd8 1487 if ($footer) {
72d497d4 1488 $output .= "<p>$footer</p>";
501cdbd8 1489 }
72d497d4 1490 $output .= "</td></tr></table>\n\n";
501cdbd8 1491
1492 return $output;
1493}
1494
1495
65b0e537 1496function forum_print_post(&$post, $courseid, $ownpost=false, $reply=false, $link=false,
f37da850 1497 $ratings=NULL, $footer="", $highlight="", $post_read=-99) {
74f5d1e3 1498
d30867b0 1499 global $USER, $CFG;
501cdbd8 1500
359f2758 1501 static $stredit, $strdelete, $strreply, $strparent, $strprune, $strpruneheading, $threadedmode, $isteacher, $adminedit;
2e2e71a8 1502
f37da850 1503 static $strmarkread, $strmarkunread;
1504
2e2e71a8 1505 if (empty($stredit)) {
359f2758 1506 $stredit = get_string('edit', 'forum');
1507 $strdelete = get_string('delete', 'forum');
1508 $strreply = get_string('reply', 'forum');
1509 $strparent = get_string('parent', 'forum');
1510 $strpruneheading = get_string('pruneheading', 'forum');
1511 $strprune = get_string('prune', 'forum');
2e2e71a8 1512 $threadedmode = (!empty($USER->mode) and ($USER->mode == FORUM_MODE_THREADED));
3bd98ad4 1513 $isteacher = isteacher($courseid);
b8be40ce 1514 $adminedit = (isadmin() and !empty($CFG->admineditalways));
f37da850 1515 $strmarkread = get_string('markread', 'forum');
1516 $strmarkunread = get_string('markunread', 'forum');
1517 }
1518
1519 if ($CFG->forum_trackreadposts) {
1520 if ($post_read == -99) { // If we don't know yet...
489de4ae 1521 /// The front page can display a news item post to non-logged in users. This should
1522 /// always appear as 'read'.
1523 $post_read = empty($USER) || forum_tp_is_post_read($USER->id, $post);
f37da850 1524 }
1525 if ($post_read) {
1526 $read_style = ' read';
1527 } else {
1528 $read_style = ' unread';
1529 echo '<a name="unread"></a>';
1530 }
1531 } else {
1532 $read_style = '';
2e2e71a8 1533 }
1534
f37da850 1535 echo '<a name="'.$post->id.'"></a>';
33200577 1536 echo '<table cellspacing="0" class="forumpost'.$read_style.'">';
501cdbd8 1537
d3583b41 1538 echo '<tr class="header"><td class="picture left">';
501cdbd8 1539 print_user_picture($post->userid, $courseid, $post->picture);
d3583b41 1540 echo '</td>';
501cdbd8 1541
1542 if ($post->parent) {
d3583b41 1543 echo '<td class="topic">';
501cdbd8 1544 } else {
d3583b41 1545 echo '<td class="topic starter">';
501cdbd8 1546 }
83ec9098 1547
1548 if (!empty($CFG->filterall)) { /// Put the subject through the filters
1c887009 1549 $post->subject = filter_text('<span class="nolink">'.$post->subject.'</span>', $courseid);
83ec9098 1550 }
d3583b41 1551 echo '<div class="subject">'.$post->subject.'</div>';
e3ff14ca 1552
d3583b41 1553 echo '<div class="author">';
3bd98ad4 1554 $fullname = fullname($post, $isteacher);
d3583b41 1555 $by->name = '<a href="'.$CFG->wwwroot.'/user/view.php?id='.
1556 $post->userid.'&amp;course='.$courseid.'">'.$fullname.'</a>';
d62413e8 1557 $by->date = userdate($post->modified);
d3583b41 1558 print_string('bynameondate', 'forum', $by);
1559 echo '</div></td></tr>';
1b26d5e7 1560
d3583b41 1561 echo '<tr><td class="left side">';
507407a7 1562 if ($group = user_group($courseid, $post->userid)) {
a4fbb0b2 1563 print_group_picture($group, $courseid, false, false, true);
507407a7 1564 } else {
d3583b41 1565 echo '&nbsp;';
507407a7 1566 }
d3583b41 1567
1568/// Actual content
1569
1570 echo '</td><td class="content">'."\n";
501cdbd8 1571
7f6689e4 1572 if ($post->attachment) {
1573 $post->course = $courseid;
d3583b41 1574 $post->forum = get_field('forum_discussions', 'forum', 'id', $post->discussion);
1575 echo '<div class="attachments">';
72d497d4 1576 $attachedimages = forum_print_attachments($post);
d3583b41 1577 echo '</div>';
e9c2dc1f 1578 } else {
d3583b41 1579 $attachedimages = '';
7f6689e4 1580 }
1581
d3583b41 1582
5be7800c 1583 if ($link and (strlen(strip_tags($post->message)) > $CFG->forum_longpost)) {
aa153f29 1584 // Print shortened version
71767204 1585 echo format_text(forum_shorten_post($post->message), $post->format, NULL, $courseid);
c585fa17 1586 $numwords = count_words(strip_tags($post->message));
d3583b41 1587 echo '<p><a href="'.$CFG->wwwroot.'/mod/forum/discuss.php?d='.$post->discussion.'">';
1588 echo get_string('readtherest', 'forum');
1589 echo '</a> ('.get_string('numwords', '', $numwords).')...</p>';
501cdbd8 1590 } else {
aa153f29 1591 // Print whole message
88438a58 1592 if ($highlight) {
71767204 1593 echo highlight($highlight, format_text($post->message, $post->format, NULL, $courseid));
88438a58 1594 } else {
71767204 1595 echo format_text($post->message, $post->format, NULL, $courseid);
88438a58 1596 }
65b0e537 1597 echo $attachedimages;
501cdbd8 1598 }
1599
d3583b41 1600
1601/// Commands
1602
359f2758 1603 $commands = array();
501cdbd8 1604
f37da850 1605 if ($CFG->forum_trackreadposts) {
489de4ae 1606 /// SPECIAL CASE: The front page can display a news item post to non-logged in users.
1607 /// Don't display the mark read / unread controls in this case.
1608 if ($CFG->forum_usermarksread && !empty($USER)) {
f37da850 1609 if ($post_read) {
1610 $mcmd = '&amp;mark=unread&amp;postid='.$post->id;
1611 $mtxt = $strmarkunread;
1612 } else {
1613 $mcmd = '&amp;mark=read&amp;postid='.$post->id;
1614 $mtxt = $strmarkread;
1615 }
1616 if ($threadedmode) {
d3583b41 1617 $commands[] = '<a href="'.$CFG->wwwroot.'/mod/forum/discuss.php?d='.
1618 $post->discussion.'&amp;parent='.$post->id.$mcmd.'">'.$mtxt.'</a>';
f37da850 1619 } else {
d3583b41 1620 $commands[] = '<a href="'.$CFG->wwwroot.'/mod/forum/discuss.php?d='.
1621 $post->discussion.$mcmd.'#'.$post->id.'">'.$mtxt.'</a>';
f37da850 1622 }
1623 }
1624 }
1625
2e2e71a8 1626 if ($post->parent) {
1627 if ($threadedmode) {
d3583b41 1628 $commands[] = '<a href="'.$CFG->wwwroot.'/mod/forum/discuss.php?d='.
1629 $post->discussion.'&amp;parent='.$post->parent.'">'.$strparent.'</a>';
2e2e71a8 1630 } else {
d3583b41 1631 $commands[] = '<a href="'.$CFG->wwwroot.'/mod/forum/discuss.php?d='.
1632 $post->discussion.'#'.$post->parent.'">'.$strparent.'</a>';
2e2e71a8 1633 }
1634 }
1635
501cdbd8 1636 $age = time() - $post->created;
b8be40ce 1637 if ($ownpost or $adminedit) {
1638 if (($age < $CFG->maxeditingtime) or $adminedit) {
d3583b41 1639 $commands[] = '<a href="'.$CFG->wwwroot.'/mod/forum/post.php?edit='.$post->id.'">'.$stredit.'</a>';
501cdbd8 1640 }
64eacd6f 1641 }
aaf7a9dc 1642
cf84431b 1643 if (isteacheredit($courseid) and $post->parent) {
d3583b41 1644 $commands[] = '<a href="'.$CFG->wwwroot.'/mod/forum/post.php?prune='.$post->id.
1645 '" title="'.$strpruneheading.'">'.$strprune.'</a>';
cf84431b 1646 }
aaf7a9dc 1647
ac00b904 1648 if (($ownpost and $age < $CFG->maxeditingtime) or $isteacher) {
d3583b41 1649 $commands[] = '<a href="'.$CFG->wwwroot.'/mod/forum/post.php?delete='.$post->id.'">'.$strdelete.'</a>';
64eacd6f 1650 }
359f2758 1651
64eacd6f 1652 if ($reply) {
d3583b41 1653 $commands[] = '<a href="'.$CFG->wwwroot.'/mod/forum/post.php?reply='.$post->id.'">'.$strreply.'</a>';
501cdbd8 1654 }
501cdbd8 1655
d3583b41 1656 echo '<div class="commands">';
1657 echo implode(' | ', $commands);
1658 echo '</div>';
1659
1660
1661/// Ratings
74f5d1e3 1662
1663 $ratingsmenuused = false;
02ebf404 1664 if (!empty($ratings) and !empty($USER->id)) {
d3583b41 1665 echo '<div class="ratings">';
98914efd 1666 $useratings = true;
1667 if ($ratings->assesstimestart and $ratings->assesstimefinish) {
1668 if ($post->created < $ratings->assesstimestart or $post->created > $ratings->assesstimefinish) {
1669 $useratings = false;
1670 }
1671 }
1672 if ($useratings) {
3bd98ad4 1673 $mypost = ($USER->id == $post->userid);
1674
1675 if (($isteacher or $ratings->assesspublic) and !$mypost) {
1676 forum_print_ratings_mean($post->id, $ratings->scale, $isteacher);
d395046a 1677 if (!empty($ratings->allow)) {
d3583b41 1678 echo '&nbsp;';
d395046a 1679 forum_print_rating_menu($post->id, $USER->id, $ratings->scale);
1680 $ratingsmenuused = true;
1681 }
3bd98ad4 1682
1683 } else if ($mypost) {
1684 forum_print_ratings_mean($post->id, $ratings->scale, true);
1685
98914efd 1686 } else if (!empty($ratings->allow) ) {
1687 forum_print_rating_menu($post->id, $USER->id, $ratings->scale);
74f5d1e3 1688 $ratingsmenuused = true;
2a3cda19 1689 }
501cdbd8 1690 }
d3583b41 1691 echo '</div>';
501cdbd8 1692 }
65b0e537 1693
d3583b41 1694/// Link to post if required
1695
501cdbd8 1696 if ($link) {
d3583b41 1697 echo '<div class="link">';
501cdbd8 1698 if ($post->replies == 1) {
d3583b41 1699 $replystring = get_string('repliesone', 'forum', $post->replies);
501cdbd8 1700 } else {
d3583b41 1701 $replystring = get_string('repliesmany', 'forum', $post->replies);
501cdbd8 1702 }
d3583b41 1703 echo '<a href="'.$CFG->wwwroot.'/mod/forum/discuss.php?d='.$post->discussion.'">'.
1704 get_string('discussthistopic', 'forum').'</a>&nbsp;('.$replystring.')';
1705 echo '</div>';
501cdbd8 1706 }
d3583b41 1707
501cdbd8 1708 if ($footer) {
d3583b41 1709 echo '<div class="footer">'.$footer.'</div>';
501cdbd8 1710 }
d3583b41 1711 echo '</td></tr></table>'."\n\n";
74f5d1e3 1712
f37da850 1713 if ($CFG->forum_trackreadposts && !$CFG->forum_usermarksread && !empty($post->forum)) {
1714 forum_tp_mark_post_read($USER->id, $post, $post->forum);
1715 }
1716
74f5d1e3 1717 return $ratingsmenuused;
501cdbd8 1718}
1719
3335f6fb 1720
3a68fbbb 1721function forum_print_discussion_header(&$post, $forum, $group=-1, $datestring="") {
43921b8a 1722/// This function prints the overview of a discussion in the forum listing.
1723/// It needs some discussion information and some post information, these
8f0cd6ef 1724/// happen to be combined for efficiency in the $post parameter by the function
43921b8a 1725/// that calls this one
1726/// forum_print_latest_discussions()
1727
d30867b0 1728 global $USER, $CFG;
3335f6fb 1729
f51e8d7e 1730 static $rowcount;
1731
1732 if (!isset($rowcount)) {
1733 $rowcount = 0;
1734 } else {
1735 $rowcount = ($rowcount + 1) % 2;
1736 }
1737
436a7cae 1738 if (!empty($CFG->filterall)) {
f51e8d7e 1739 $post->subject = filter_text('<span class="nolink">'.$post->subject.'</span>', $forum->course);
436a7cae 1740 }
1741
f51e8d7e 1742 echo "\n\n";
1743 echo '<tr class="discussion r'.$rowcount.'">';
3335f6fb 1744
29507631 1745 // Topic
f51e8d7e 1746 echo '<td class="topic starter">';
1747 echo '<a href="'.$CFG->wwwroot.'/mod/forum/discuss.php?d='.$post->discussion.'">'.$post->subject.'</a>';
29507631 1748 echo "</td>\n";
1749
1750 // Picture
f51e8d7e 1751 echo '<td class="picture">';
a796d0b8 1752 print_user_picture($post->userid, $forum->course, $post->picture);
29507631 1753 echo "</td>\n";
3335f6fb 1754
29507631 1755 // User name
a796d0b8 1756 $fullname = fullname($post, isteacher($forum->course));
f51e8d7e 1757 echo '<td class="author">';
1758 echo '<a href="'.$CFG->wwwroot.'/user/view.php?id='.$post->userid.'&amp;course='.$forum->course.'">'.$fullname.'</a>';
29507631 1759 echo "</td>\n";
1760
3a68fbbb 1761 // Group picture
425b4f1a 1762 if ($group !== -1) { // Groups are active - group is a group data object or NULL
f51e8d7e 1763 echo '<td class="picture group">';
c2b552fe 1764 if (!empty($group->picture) and empty($group->hidepicture)) {
3a68fbbb 1765 print_group_picture($group, $forum->course, false, false, true);
1766 } else if (isset($group->id)) {
1767 echo '<a href="'.$CFG->wwwroot.'/course/group.php?id='.$forum->course.'&amp;group='.$group->id.'">'.$group->name.'</a>';
1768 }
1769 echo "</td>\n";
1770 }
1771
f51e8d7e 1772 if ($forum->open or $forum->type == 'teacher') { // Show the column with replies
1773 echo '<td class="replies">';
1774 echo '<a href="'.$CFG->wwwroot.'/mod/forum/discuss.php?d='.$post->discussion.'">';
1775 echo $post->replies.'</a>';
a796d0b8 1776 echo "</td>\n";
e3ff14ca 1777
f37da850 1778 if ($CFG->forum_trackreadposts) {
f51e8d7e 1779 echo '<td class="replies">';
1780 echo '<a href="'.$CFG->wwwroot.'/mod/forum/discuss.php?d='.$post->discussion.'#unread">';
3a68fbbb 1781 if ($post->unread > 0) {
f51e8d7e 1782 echo '<span class="unread">'.$post->unread.'</span>';
1783 } else {
1784 echo $post->unread;
3a68fbbb 1785 }
f37da850 1786 echo '</a>';
1787 echo "</td>\n";
1788 }
1789
a796d0b8 1790 }
3335f6fb 1791
f51e8d7e 1792 echo '<td class="lastpost">';
43921b8a 1793 $usedate = (empty($post->timemodified)) ? $post->modified : $post->timemodified; // Just in case
839f2456 1794 $parenturl = (empty($post->lastpostid)) ? '' : '&amp;parent='.$post->lastpostid;
268c6485 1795 $usermodified->firstname = $post->umfirstname;
1796 $usermodified->lastname = $post->umlastname;
f51e8d7e 1797 echo '<a href="'.$CFG->wwwroot.'/user/view.php?id='.$post->usermodified.'&amp;course='.$forum->course.'">'.
1798 fullname($usermodified).'</a><br />';
ac00b904 1799 echo '<a href="'.$CFG->wwwroot.'/mod/forum/discuss.php?d='.$post->discussion.$parenturl.'">'.
43921b8a 1800 userdate($usedate, $datestring).'</a>';
29507631 1801 echo "</td>\n";
1802
f51e8d7e 1803 echo "</tr>\n\n";
3335f6fb 1804
3335f6fb 1805}
1806
1807
aa153f29 1808function forum_shorten_post($message) {
c585fa17 1809// Given a post object that we already know has a long message
65b0e537 1810// this function truncates the message nicely to the first
5be7800c 1811// sane place between $CFG->forum_longpost and $CFG->forum_shortpost
1812
1813 global $CFG;
c585fa17 1814
1815 $i = 0;
1816 $tag = false;
1817 $length = strlen($message);
1818 $count = 0;
1819 $stopzone = false;
1820 $truncate = 0;
1821
1822 for ($i=0; $i<$length; $i++) {
a8afb411 1823 $char = $message[$i];
c585fa17 1824
1825 switch ($char) {
65b0e537 1826 case "<":
c585fa17 1827 $tag = true;
1828 break;
65b0e537 1829 case ">":
c585fa17 1830 $tag = false;
1831 break;
1832 default:
1833 if (!$tag) {
1834 if ($stopzone) {
67f0b4cc 1835 if ($char == ".") {
a8afb411 1836 $truncate = $i+1;
c585fa17 1837 break 2;
1838 }
1839 }
1840 $count++;
1841 }
a8afb411 1842 break;
c585fa17 1843 }
1844 if (!$stopzone) {
5be7800c 1845 if ($count > $CFG->forum_shortpost) {
c585fa17 1846 $stopzone = true;
1847 }
1848 }
1849 }
aa153f29 1850
c585fa17 1851 if (!$truncate) {
a8afb411 1852 $truncate = $i;
c585fa17 1853 }
1854
67f0b4cc 1855 return substr($message, 0, $truncate);
aa153f29 1856}
1857
501cdbd8 1858
3bd98ad4 1859function forum_print_ratings_mean($postid, $scale, $link=true) {
02ebf404 1860/// Print the multiple ratings on a post given to the current user by others.
1861/// Scale is an array of ratings
1862
1863 static $strrate;
05c47ef7 1864
1865 $mean = forum_get_ratings_mean($postid, $scale);
65b0e537 1866
05c47ef7 1867 if ($mean !== "") {
02ebf404 1868
1869 if (empty($strratings)) {
1870 $strratings = get_string("ratings", "forum");
501cdbd8 1871 }
501cdbd8 1872
02ebf404 1873 echo "$strratings: ";
3bd98ad4 1874 if ($link) {
1875 link_to_popup_window ("/mod/forum/report.php?id=$postid", "ratings", $mean, 400, 600);
1876 } else {
1877 echo "$mean ";
1878 }
501cdbd8 1879 }
1880}
1881
501cdbd8 1882
0761d83f 1883function forum_get_ratings_mean($postid, $scale, $ratings=NULL) {
1884/// Return the mean rating of a post given to the current user by others.
02ebf404 1885/// Scale is an array of possible ratings in the scale
1886/// Ratings is an optional simple array of actual ratings (just integers)
1887
1888 if (!$ratings) {
1889 $ratings = array();
1890 if ($rates = get_records("forum_ratings", "post", $postid)) {
1891 foreach ($rates as $rate) {
1892 $ratings[] = $rate->rating;
1893 }
501cdbd8 1894 }
501cdbd8 1895 }
02ebf404 1896
0761d83f 1897 $count = count($ratings);
1898
1899 if ($count == 0) {
02ebf404 1900 return "";
02ebf404 1901
0761d83f 1902 } else if ($count == 1) {
1903 return $scale[$ratings[0]];
1904
02ebf404 1905 } else {
0761d83f 1906 $total = 0;
1907 foreach ($ratings as $rating) {
1908 $total += $rating;
1909 }
1910 $mean = round( ((float)$total/(float)$count) + 0.001); // Little fudge factor so that 0.5 goes UP
65b0e537 1911
0761d83f 1912 if (isset($scale[$mean])) {
1913 return $scale[$mean]." ($count)";
1914 } else {
1915 return "$mean ($count)"; // Should never happen, hopefully
1916 }
02ebf404 1917 }
1918}
1919
1920function forum_get_ratings_summary($postid, $scale, $ratings=NULL) {
1921/// Return a summary of post ratings given to the current user by others.
1922/// Scale is an array of possible ratings in the scale
1923/// Ratings is an optional simple array of actual ratings (just integers)
1924
1925 if (!$ratings) {
1926 $ratings = array();
1927 if ($rates = get_records("forum_ratings", "post", $postid)) {
1928 foreach ($rates as $rate) {
1929 $rating[] = $rate->rating;
1930 }
1931 }
1932 }
1933
1934
1935 if (!$count = count($ratings)) {
1936 return "";
1937 }
1938
1939
1940 foreach ($scale as $key => $scaleitem) {
1941 $sumrating[$key] = 0;
1942 }
1943
1944 foreach ($ratings as $rating) {
1945 $sumrating[$rating]++;
1946 }
1947
1948 $summary = "";
1949 foreach ($scale as $key => $scaleitem) {
1950 $summary = $sumrating[$key].$summary;
1951 if ($key > 1) {
1952 $summary = "/$summary";
1953 }
1954 }
1955 return $summary;
1956}
1957
1958function forum_print_rating_menu($postid, $userid, $scale) {
65b0e537 1959/// Print the menu of ratings as part of a larger form.
02ebf404 1960/// If the post has already been - set that value.
1961/// Scale is an array of ratings
1962
1963 static $strrate;
1964
1965 if (!$rating = get_record("forum_ratings", "userid", $userid, "post", $postid)) {
1966 $rating->rating = 0;
1967 }
1968
1969 if (empty($strrate)) {
1970 $strrate = get_string("rate", "forum");
1971 }
1972
1973 choose_from_menu($scale, $postid, $rating->rating, "$strrate...");
501cdbd8 1974}
1975
7a12aab4 1976function forum_print_mode_form($discussion, $mode) {
1977 GLOBAL $FORUM_LAYOUT_MODES;
501cdbd8 1978
839f2456 1979 echo "<div align=\"center\">";
1980 popup_form("discuss.php?d=$discussion&amp;mode=", $FORUM_LAYOUT_MODES, "mode", $mode, "");
1981 echo "</div>\n";
501cdbd8 1982}
1983
6f1cc8d6 1984function forum_search_form($course, $search='') {
501cdbd8 1985 global $CFG;
1986
6f1cc8d6 1987 $output = '<table border="0" cellpadding="0" cellspacing="0"><tr><td nowrap="nowrap">';
1988 $output .= helpbutton('search', get_string('search'), 'moodle', true, false, '', true);
1989 $output .= '&nbsp;<form name="search" action="'.$CFG->wwwroot.'/mod/forum/search.php" style="display:inline">';
1990 $output .= '<input name="search" type="text" size="18" value="'.$search.'" alt="search" />';
1991 $output .= '<input value="'.get_string('searchforums', 'forum').'" type="submit" />';
1992 $output .= '<input name="id" type="hidden" value="'.$course->id.'" />';
1993 $output .= '</form>';
1994 $output .= '</td></tr></table>';
5e367a2d 1995
6f1cc8d6 1996 return $output;
501cdbd8 1997}
1998
1999
11b0c469 2000function forum_set_return() {
607809b3 2001 global $CFG, $SESSION;
501cdbd8 2002
28e1e8b9 2003 if (! isset($SESSION->fromdiscussion)) {
48d38fad 2004 if (!empty($_SERVER['HTTP_REFERER'])) {
2005 $referer = $_SERVER['HTTP_REFERER'];
2006 } else {
2007 $referer = "";
2008 }
28e1e8b9 2009 // If the referer is NOT a login screen then save it.
48d38fad 2010 if (! strncasecmp("$CFG->wwwroot/login", $referer, 300)) {
607809b3 2011 $SESSION->fromdiscussion = $_SERVER["HTTP_REFERER"];
28e1e8b9 2012 }
501cdbd8 2013 }
2014}
2015
2016
11b0c469 2017function forum_go_back_to($default) {
501cdbd8 2018 global $SESSION;
2019
9c9f7d77 2020 if (!empty($SESSION->fromdiscussion)) {
501cdbd8 2021 $returnto = $SESSION->fromdiscussion;
2022 unset($SESSION->fromdiscussion);
2023 return $returnto;
2024 } else {
2025 return $default;
2026 }
2027}
2028
7f6689e4 2029function forum_file_area_name($post) {
2030// Creates a directory file name, suitable for make_upload_directory()
2031 global $CFG;
2032
2033 return "$post->course/$CFG->moddata/forum/$post->forum/$post->id";
2034}
2035
2036function forum_file_area($post) {
2037 return make_upload_directory( forum_file_area_name($post) );
2038}
2039
2040function forum_delete_old_attachments($post, $exception="") {
2041// Deletes all the user files in the attachments area for a post
2042// EXCEPT for any file named $exception
2043
2044 if ($basedir = forum_file_area($post)) {
2045 if ($files = get_directory_list($basedir)) {
2046 foreach ($files as $file) {
2047 if ($file != $exception) {
2048 unlink("$basedir/$file");
2049 notify("Existing file '$file' has been deleted!");
2050 }
2051 }
2052 }
2053 if (!$exception) { // Delete directory as well, if empty
2054 rmdir("$basedir");
2055 }
2056 }
2057}
2058
cc2b7ea5 2059function forum_move_attachments($discussion, $forumid) {
65b0e537 2060/// Given a discussion object that is being moved to forumid,
2061/// this function checks all posts in that discussion
2062/// for attachments, and if any are found, these are
cc2b7ea5 2063/// moved to the new forum directory.
2064
2065 global $CFG;
2066
18b8fbfa 2067 require_once($CFG->dirroot.'/lib/uploadlib.php');
2068
cc2b7ea5 2069 $return = true;
2070
2071 if ($posts = get_records_select("forum_posts", "discussion = '$discussion->id' AND attachment <> ''")) {
2072 foreach ($posts as $oldpost) {
2073 $oldpost->course = $discussion->course;
2074 $oldpost->forum = $discussion->forum;
2075 $oldpostdir = "$CFG->dataroot/".forum_file_area_name($oldpost);
2076 if (is_dir($oldpostdir)) {
2077 $newpost = $oldpost;
2078 $newpost->forum = $forumid;
7f0c3a44 2079 $newpostdir = forum_file_area($newpost);
18b8fbfa 2080 $files = get_directory_list($oldpostdir); // get it before we rename it.
cc2b7ea5 2081 if (! @rename($oldpostdir, $newpostdir)) {
2082 $return = false;
2083 }
18b8fbfa 2084 foreach ($files as $file) {
2085 clam_change_log($oldpostdir.'/'.$file,$newpostdir.'/'.$file);
2086 }
cc2b7ea5 2087 }
2088 }
2089 }
2090 return $return;
2091}
2092
7f6689e4 2093function forum_print_attachments($post, $return=NULL) {
2094// if return=html, then return a html string.
2095// if return=text, then return a text-only string.
72d497d4 2096// otherwise, print HTML for non-images, and return image HTML
7f6689e4 2097
2098 global $CFG;
2099
2100 $filearea = forum_file_area_name($post);
2101
72d497d4 2102 $imagereturn = "";
2103 $output = "";
2104
7f6689e4 2105 if ($basedir = forum_file_area($post)) {
2106 if ($files = get_directory_list($basedir)) {
2107 $strattachment = get_string("attachment", "forum");
6afe8558 2108 $strpopupwindow = get_string("popupwindow");
7f6689e4 2109 foreach ($files as $file) {
2110 $icon = mimeinfo("icon", $file);
2111 if ($CFG->slasharguments) {
2112 $ffurl = "file.php/$filearea/$file";
2113 } else {
2114 $ffurl = "file.php?file=/$filearea/$file";
2115 }
839f2456 2116 $image = "<img border=\"0\" src=\"$CFG->pixpath/f/$icon\" height=\"16\" width=\"16\" alt=\"$strpopupwindow\" />";
7f6689e4 2117
2118 if ($return == "html") {
6afe8558 2119 $output .= "<a href=\"$CFG->wwwroot/$ffurl\">$image</a> ";
2120 $output .= "<a href=\"$CFG->wwwroot/$ffurl\">$file</a><br />";
7f6689e4 2121
2122 } else if ($return == "text") {
2123 $output .= "$strattachment $file:\n$CFG->wwwroot/$ffurl\n";
2124
2125 } else {
72d497d4 2126 if ($icon == "image.gif") { // Image attachments don't get printed as links
839f2456 2127 $imagereturn .= "<br /><img src=\"$CFG->wwwroot/$ffurl\" alt=\"\" />";
72d497d4 2128 } else {
2129 link_to_popup_window("/$ffurl", "attachment", $image, 500, 500, $strattachment);
2130 echo "<a href=\"$CFG->wwwroot/$ffurl\">$file</a>";
2131 echo "<br />";
2132 }
7f6689e4 2133 }
2134 }
2135 }
2136 }
72d497d4 2137
7f6689e4 2138 if ($return) {
2139 return $output;
2140 }
72d497d4 2141
2142 return $imagereturn;
7f6689e4 2143}
db290a6e 2144/**
e3ff14ca 2145 * If successful, this function returns the name of the file
db290a6e 2146 * @param $post is a full post record, including course and forum
2147 * @param $newfile is a full upload array from $_FILES
2148 * @param $message is a string to hold the messages.
e3ff14ca 2149 */
7f6689e4 2150
db290a6e 2151function forum_add_attachment($post, $inputname,&$message) {
7f6689e4 2152
9dd0b378 2153 global $CFG;
2154
4909e176 2155 if (!$forum = get_record("forum", "id", $post->forum)) {
2156 return "";
2157 }
2158
2159 if (!$course = get_record("course", "id", $forum->course)) {
2160 return "";
2161 }
2162
5ddaa2e2 2163 require_once($CFG->dirroot.'/lib/uploadlib.php');
db290a6e 2164 $um = new upload_manager($inputname,true,false,$course,false,$forum->maxbytes,true,true);
5ddaa2e2 2165 $dir = forum_file_area_name($post);
2166 if ($um->process_file_uploads($dir)) {
db290a6e 2167 $message .= $um->get_errors();
5ddaa2e2 2168 return $um->get_new_filename();
7f6689e4 2169 }
db290a6e 2170 $message .= $um->get_errors();
7f6689e4 2171}
501cdbd8 2172
db290a6e 2173function forum_add_new_post($post,&$message) {
501cdbd8 2174
f37da850 2175 global $USER, $CFG;
e3ff14ca 2176
ffe11640 2177 $post->created = $post->modified = time();
501cdbd8 2178 $post->mailed = "0";
a56f0d60 2179 $post->userid = $USER->id;
7f6689e4 2180 $post->attachment = "";
2181
65b0e537 2182 if (! $post->id = insert_record("forum_posts", $post)) {
7f6689e4 2183 return false;
2184 }
2185
db290a6e 2186 if ($post->attachment = forum_add_attachment($post, 'attachment',$message)) {
7f6689e4 2187 set_field("forum_posts", "attachment", $post->attachment, "id", $post->id);
2188 }
29507631 2189
2190 // Update discussion modified date
2191 set_field("forum_discussions", "timemodified", $post->modified, "id", $post->discussion);
016cd6af 2192 set_field("forum_discussions", "usermodified", $post->userid, "id", $post->discussion);
65b0e537 2193
f37da850 2194 if ($CFG->forum_trackreadposts) {
2195 forum_tp_mark_post_read($post->userid, $post, $post->forum);
2196 }
2197
7f6689e4 2198 return $post->id;
501cdbd8 2199}
2200
db290a6e 2201function forum_update_post($post,&$message) {
501cdbd8 2202
f37da850 2203 global $USER, $CFG;
a56f0d60 2204
ffe11640 2205 $post->modified = time();
0936de64 2206
2207 if ($USER->id != $post->userid) { // Not the original author
2208 $data->name = '<a href="'.$CFG->wwwroot.'/user/view.php?id='.$USER->id.'&course='.$post->course.'">'.
2209 fullname($USER).'</a>';
2210 $data->date = userdate($post->modified);
2211 $editedby = get_string('editedby', 'forum', $data);
2212 if ($post->format == FORMAT_HTML) {
0d2c0cfd 2213 $post->message .= '<p>(<i><span class="edited">'.$editedby.'</span></i>)</p>';
0936de64 2214 } else {
2215 $post->message .= "\n\n(".$editedby.')';
2216 }
2217 }
501cdbd8 2218
0ab85112 2219 if (!$post->parent) { // Post is a discussion starter - update discussion title too
2220 set_field("forum_discussions", "name", $post->subject, "id", $post->discussion);
2221 }
29507631 2222
db290a6e 2223 if ($newfilename = forum_add_attachment($post, 'attachment',$message)) {
7f6689e4 2224 $post->attachment = $newfilename;
2225 } else {
2226 unset($post->attachment);
2227 }
29507631 2228
2229 // Update discussion modified date
2230 set_field("forum_discussions", "timemodified", $post->modified, "id", $post->discussion);
016cd6af 2231 set_field("forum_discussions", "usermodified", $post->userid, "id", $post->discussion);
29507631 2232
f37da850 2233 if ($CFG->forum_trackreadposts) {
2234 forum_tp_mark_post_read($post->userid, $post, $post->forum);
2235 }
2236
ffe11640 2237 return update_record("forum_posts", $post);
501cdbd8 2238}
2239
db290a6e 2240function forum_add_discussion($discussion,&$message) {
65b0e537 2241// Given an object containing all the necessary data,
501cdbd8 2242// create a new discussion and return the id
2243
f37da850 2244 GLOBAL $USER, $CFG;
501cdbd8 2245
2246 $timenow = time();
2247
65b0e537 2248 // The first post is stored as a real post, and linked
501cdbd8 2249 // to from the discuss entry.
2250
2251 $post->discussion = 0;
2252 $post->parent = 0;
ebc3bd2b 2253 $post->userid = $USER->id;
501cdbd8 2254 $post->created = $timenow;
2255 $post->modified = $timenow;
2256 $post->mailed = 0;
2257 $post->subject = $discussion->name;
2258 $post->message = $discussion->intro;
7f6689e4 2259 $post->attachment = "";
2260 $post->forum = $discussion->forum;
2261 $post->course = $discussion->course;
9f0b8269 2262 $post->format = $discussion->format;
501cdbd8 2263
2264 if (! $post->id = insert_record("forum_posts", $post) ) {
2265 return 0;
2266 }
2267
db290a6e 2268 if ($post->attachment = forum_add_attachment($post, 'attachment',$message)) {
7f6689e4 2269 set_field("forum_posts", "attachment", $post->attachment, "id", $post->id); //ignore errors
2270 }
2271
65b0e537 2272 // Now do the main entry for the discussion,
02509fe6 2273 // linking to this first post
04eba58f 2274
caadf009 2275 $discussion->firstpost = $post->id;
2276 $discussion->timemodified = $timenow;
016cd6af 2277 $discussion->usermodified = $post->userid;
a56f0d60 2278 $discussion->userid = $USER->id;
04eba58f 2279
4e00a4d9 2280 if (! $post->discussion = insert_record("forum_discussions", $discussion) ) {
caadf009 2281 delete_records("forum_posts", "id", $post->id);
2282 return 0;
04eba58f 2283 }
2284
caadf009 2285 // Finally, set the pointer on the post.
4e00a4d9 2286 if (! set_field("forum_posts", "discussion", $post->discussion, "id", $post->id)) {
caadf009 2287 delete_records("forum_posts", "id", $post->id);
4e00a4d9 2288 delete_records("forum_discussions", "id", $post->discussion);
caadf009 2289 return 0;
04eba58f 2290 }
04eba58f 2291
f37da850 2292 if ($CFG->forum_trackreadposts) {
2293 forum_tp_mark_post_read($post->userid, $post, $post->forum);
2294 }
2295
4e00a4d9 2296 return $post->discussion;
caadf009 2297}
04eba58f 2298
04eba58f 2299
caadf009 2300function forum_delete_discussion($discussion) {
2301// $discussion is a discussion record object
04eba58f 2302
2303 $result = true;
2304
caadf009 2305 if ($posts = get_records("forum_posts", "discussion", $discussion->id)) {
2306 foreach ($posts as $post) {
2307 $post->course = $discussion->course;
2308 $post->forum = $discussion->forum;
2309 if (! delete_records("forum_ratings", "post", "$post->id")) {
2310 $result = false;
2311 }
2312 if (! forum_delete_post($post)) {
04eba58f 2313 $result = false;
2314 }
2315 }
2316 }
2317
f37da850 2318 forum_tp_delete_read_records(-1, -1, $discussion->id);
2319
caadf009 2320 if (! delete_records("forum_discussions", "id", "$discussion->id")) {
04eba58f 2321 $result = false;
2322 }
2323
2324 return $result;
2325}
2326
2327
caadf009 2328function forum_delete_post($post) {
2329 if (delete_records("forum_posts", "id", $post->id)) {
2330 delete_records("forum_ratings", "post", $post->id); // Just in case
f37da850 2331
2332 forum_tp_delete_read_records(-1, $post->id);
2333
caadf009 2334 if ($post->attachment) {
2335 $discussion = get_record("forum_discussions", "id", $post->discussion);
2336 $post->course = $discussion->course;
2337 $post->forum = $discussion->forum;
2338 forum_delete_old_attachments($post);
2339 }
2340 return true;
2341 }
2342 return false;
2343}
501cdbd8 2344
501cdbd8 2345
b656e2a9 2346function forum_print_user_discussions($courseid, $userid, $groupid=0) {
caadf009 2347 global $CFG, $USER;
501cdbd8 2348
b8bf90c5 2349 $maxdiscussions = 10;
2350 $countdiscussions = 0;
2351
65b0e537 2352 $visible = array();
1f48942e 2353
2862b309 2354 $course = get_record("course", "id", $courseid);
2355
2356 $currentgroup = get_current_group($courseid);
2357 $isteacheredit = isteacheredit($courseid);
2358
b656e2a9 2359 if ($discussions = forum_get_user_discussions($courseid, $userid, $groupid=0)) {
2862b309 2360
2361 $user = get_record("user", "id", $userid);
1b26d5e7 2362 $fullname = fullname($user, isteacher($courseid));
2862b309 2363
a48e8c4b 2364 $replies = forum_count_discussion_replies(0,$courseid,$userid);
2862b309 2365
2366 echo "<hr />";
2367
2368 print_heading( get_string("discussionsstartedbyrecent", "forum", $fullname) );
2369
173dbed4 2370 echo '<p align="center" class="allposts">';
2371 echo '(<a href="'.$CFG->wwwroot.'/mod/forum/search.php?id='.$courseid.'&amp;userid='.$userid.'">';
2372 echo get_string('seeallposts', 'forum');
2373 echo '</a>)';
2374 echo '</p>';
2375
caadf009 2376 foreach ($discussions as $discussion) {
b8bf90c5 2377 $countdiscussions++;
2378 if ($countdiscussions > $maxdiscussions) {
2379 break;
2380 }
caadf009 2381 if (($discussion->forumtype == "teacher") and !isteacher($courseid)) {
ffe11640 2382 continue;
2383 }
65b0e537 2384 if(!isset($visible[$discussion->forumid])) {
2385 $mod = New stdClass;
2386 $mod->course = $courseid;
2387 $mod->id = $discussion->forumid;
2388 $visible[$discussion->forumid] = instance_is_visible('forum', $mod);
2389 }
2390 if(!$visible[$discussion->forumid] && !isteacheredit($courseid, $USER->id)) {
2391 continue;
2392 }
2862b309 2393
2394 /// Check whether this is belongs to a discussion in a group that
2395 /// should NOT be accessible to the current user
2396
2397 if (!$isteacheredit and $discussion->groupid != -1) { /// Editing teachers or open discussions
7b07a935 2398 if (!isset($cm[$discussion->forumid])) {
2399 $cm[$discussion->forumid] = get_coursemodule_from_instance("forum", $discussion->forumid, $courseid);
2400 $groupmode[$discussion->forumid] = groupmode($course, $cm[$discussion->forumid]);
2862b309 2401 }
7b07a935 2402 if ($groupmode[$discussion->forumid] == SEPARATEGROUPS) {
2862b309 2403 if ($currentgroup != $discussion->groupid) {
2404 continue;
2405 }
2406 }
2407 }
2408
47f1da80 2409 if (!empty($replies[$discussion->discussion])) {
caadf009 2410 $discussion->replies = $replies[$discussion->discussion]->replies;
2411 } else {
2412 $discussion->replies = 0;
501cdbd8 2413 }
41905731 2414 $inforum = get_string("inforum", "forum", "<a href=\"$CFG->wwwroot/mod/forum/view.php?f=$discussion->forumid\">$discussion->forumname</a>");
caadf009 2415 $discussion->subject .= " ($inforum)";
61e96406 2416 if (!empty($USER->id)) {
2417 $ownpost = ($discussion->userid == $USER->id);
2418 } else {
2419 $ownpost = false;
2420 }
caadf009 2421 forum_print_post($discussion, $courseid, $ownpost, $reply=0, $link=1, $assessed=false);
501cdbd8 2422 }
b23c06ad 2423 } else {
2424 echo '<p align="center" class="allposts">';
2425 echo '<a href="'.$CFG->wwwroot.'/mod/forum/search.php?id='.$courseid.'&amp;userid='.$userid.'">';
2426 echo get_string('seeallposts', 'forum');
2427 echo '</a>';
2428 echo '</p>';
501cdbd8 2429 }
501cdbd8 2430}
2431
501cdbd8 2432function forum_forcesubscribe($forumid, $value=1) {
2433 return set_field("forum", "forcesubscribe", $value, "id", $forumid);
2434}
2435
2436function forum_is_forcesubscribed($forumid) {
709f0ec8 2437 return (get_field("forum", "forcesubscribe", "id", $forumid) == 1);
501cdbd8 2438}
2439
2440function forum_is_subscribed($userid, $forumid) {
2441 if (forum_is_forcesubscribed($forumid)) {
2442 return true;
2443 }
ebc3bd2b 2444 return record_exists("forum_subscriptions", "userid", $userid, "forum", $forumid);
86970225 2445}
2446
501cdbd8 2447function forum_subscribe($userid, $forumid) {
9fa49e22 2448/// Adds user to the subscriber list
2449
6673d7bd 2450 if (record_exists("forum_subscriptions", "userid", $userid, "forum", $forumid)) {
2451 return true;
2452 }
2453
ebc3bd2b 2454 $sub->userid = $userid;
9fa49e22 2455 $sub->forum = $forumid;
501cdbd8 2456
9fa49e22 2457 return insert_record("forum_subscriptions", $sub);
501cdbd8 2458}
2459
2460function forum_unsubscribe($userid, $forumid) {
9fa49e22 2461/// Removes user from the subscriber list
ebc3bd2b 2462 return delete_records("forum_subscriptions", "userid", $userid, "forum", $forumid);
501cdbd8 2463}
2464
0a9f61b5 2465function forum_post_subscription($post) {
2466/// Given a new post, subscribes or unsubscribes as appropriate.
2467/// Returns some text which describes what happened.
2468
2469 global $USER;
2470
2471 if (empty($post->subscribe) and empty($post->unsubscribe)) {
2472 return "";
2473 }
2474
2475 if (!$forum = get_record("forum", "id", $post->forum)) {
2476 return "";
2477 }
2478
067675c0 2479 $info->name = fullname($USER);
0a9f61b5 2480 $info->forum = $forum->name;
2481
2482 if (!empty($post->subscribe)) {
2483 forum_subscribe($USER->id, $post->forum);
2484 return "<p>".get_string("nowsubscribed", "forum", $info)."</p>";
2485 }
2486
2487 forum_unsubscribe($USER->id, $post->forum);
2488 return "<p>".get_string("nownotsubscribed", "forum", $info)."</p>";
2489}
2490
501cdbd8 2491
11b0c469 2492function forum_user_has_posted_discussion($forumid, $userid) {
29507631 2493 if ($discussions = forum_get_discussions($forumid, "", $userid)) {
501cdbd8 2494 return true;
2495 } else {
2496 return false;
2497 }
2498}
2499
9197e147 2500function forum_user_can_post_discussion($forum, $currentgroup=false) {
501cdbd8 2501// $forum is an object
2502 global $USER;
2503
2504 if ($forum->type == "eachuser") {
11b0c469 2505 return (! forum_user_has_posted_discussion($forum->id, $USER->id));
501cdbd8 2506 } else if ($forum->type == "teacher") {
2507 return isteacher($forum->course);
9197e147 2508 } else if ($currentgroup) {
d591b40f 2509 return (isteacheredit($forum->course) or (ismember($currentgroup) and $forum->open == 2));
501cdbd8 2510 } else if (isteacher($forum->course)) {
2511 return true;
2512 } else {
70c476a7 2513 return ($forum->open == 2);
501cdbd8 2514 }
2515}
2516
f690562f 2517function forum_user_can_post($forum, $user=NULL) {
2518// $forum, $user are objects
2519
2520 if ($user) {
2521 $isteacher = isteacher($forum->course, $user->id);
2522 } else {
2523 $isteacher = isteacher($forum->course);
2524 }
70c476a7 2525
2526 if ($forum->type == "teacher") {
f690562f 2527 return $isteacher;
2528 } else if ($isteacher) {
70c476a7 2529 return true;
2530 } else {
2531 return $forum->open;
2532 }
2533}
501cdbd8 2534
501cdbd8 2535
af328e4b 2536function forum_print_latest_discussions($course, $forum, $maxdiscussions=5, $displayformat='plain', $sort='',
2537 $currentgroup=-1, $groupmode=-1, $page=-1) {
c585fa17 2538 global $CFG, $USER;
65b0e537 2539
f93f848a 2540
af328e4b 2541/// Sort out some defaults
2542
2543 if ((!$maxdiscussions) && ($displayformat == 'plain')) {
2544 $displayformat = 'header'; // Abbreviate display by default
2545 }
2546
2547 $fullpost = false;
2548 if ($displayformat == 'plain') {
2549 $fullpost = true;
f93f848a 2550 }
2551
af328e4b 2552
2553/// Decide if current user is allowed to see ALL the current discussions or not
2554
2555/// First check the group stuff
2556
2862b309 2557 if ($groupmode == -1) { /// We need to reconstruct groupmode because none was given
d5bbc556 2558 if ($cm = get_coursemodule_from_instance('forum', $forum->id, $course->id)) {
2862b309 2559 $groupmode = groupmode($course, $cm);
2560 } else {
2561 $groupmode = SEPARATEGROUPS;
2562 }
2563 }
8f0cd6ef 2564
af328e4b 2565 if ($currentgroup == -1) { /// We need to reconstruct currentgroup because none was given
2566 $currentgroup = get_current_group($course->id);
2567 }
2568
2569 if (!$currentgroup and ($groupmode != SEPARATEGROUPS or isteacheredit($course->id)) ) {
2570 $visiblegroups = -1;
2571 } else {
2572 $visiblegroups = $currentgroup;
2573 }
2574
2575/// If the user can post discussions, then this is a good place to put the button for it
2862b309 2576
9197e147 2577 if (forum_user_can_post_discussion($forum, $currentgroup)) {
af328e4b 2578 echo '<div class="singlebutton forumaddnew">';
49aa3742 2579 echo "<form name=\"newdiscussionform\" method=\"get\" action=\"$CFG->wwwroot/mod/forum/post.php\">";
2580 echo "<input type=\"hidden\" name=\"forum\" value=\"$forum->id\" />";
2581 echo '<input type="submit" value="';
d5bbc556 2582 echo ($forum->type == 'news') ? get_string('addanewtopic', 'forum') : get_string('addanewdiscussion', 'forum');
49aa3742 2583 echo '" />';
2584 echo '</form>';
3479c82f 2585 echo "</div>\n";
77305fe6 2586 }
2587
2862b309 2588
2589/// Get all the recent discussions we're allowed to see
2590
af328e4b 2591 if (! $discussions = forum_get_discussions($forum->id, $sort, 0, $fullpost, $visiblegroups) ) {
2592 echo '<div class="forumnodiscuss">';
d5bbc556 2593 if ($forum->type == 'news') {
2594 echo '('.get_string('nonews', 'forum').')';
0351b1f9 2595 } else {
d5bbc556 2596 echo '('.get_string('nodiscussions', 'forum').')';
0351b1f9 2597 }
f13075f1 2598 echo "</div>\n";
2ab968e9 2599 return;
2600 }
65b0e537 2601
af328e4b 2602/// If no discussions then don't use paging (to avoid some divide by 0 errors)
2603
2604 if ($maxdiscussions <= 0) {
f6bb7eaa 2605 $page = -1;
af328e4b 2606 $maxdiscussions = 0;
f6bb7eaa 2607 }
2608
af328e4b 2609/// If we want paging
2610
f6bb7eaa 2611 if ($page != -1) {
2612 ///Get the number of discussions found
2613 $numdiscussions = count($discussions);
2614
2615 ///Show the paging bar
af328e4b 2616 print_paging_bar($numdiscussions, $page, $maxdiscussions, "view.php?f=$forum->id&");
f6bb7eaa 2617
2618 //Calculate the page "window"
af328e4b 2619 $pagestart = ($page * $maxdiscussions) + 1;
2620 $pageend = $pagestart + $maxdiscussions - 1;
f6bb7eaa 2621 }
2622
af328e4b 2623
3335f6fb 2624 $replies = forum_count_discussion_replies($forum->id);
f93f848a 2625
3260de67 2626 $canreply = forum_user_can_post($forum);
2627
af328e4b 2628
3335f6fb 2629 $discussioncount = 0;
c20b762a 2630 $olddiscussionlink = false;
f51e8d7e 2631 $strdatestring = get_string('strftimerecentfull');
f93f848a 2632
af328e4b 2633 if ($displayformat == 'header') {
f51e8d7e 2634 echo '<table class="forumheaderlist">';
2635 echo '<thead>';
2636 echo '<tr>';
2637 echo '<th class="topic">'.get_string('discussion', 'forum').'</th>';
2638 echo '<th class="author" colspan="2">'.get_string('startedby', 'forum').'</th>';
3a68fbbb 2639 if ($groupmode > 0) {
f51e8d7e 2640 echo '<th class="group">'.get_string('group').'</th>';
3a68fbbb 2641 }
f51e8d7e 2642 if ($forum->open or $forum->type == 'teacher') {
2643 echo '<th class="replies">'.get_string('replies', 'forum').'</th>';
a796d0b8 2644 }
f37da850 2645 if ($CFG->forum_trackreadposts) {
f51e8d7e 2646 echo '<th class="replies">'.get_string('unread', 'forum').'</th>';
f37da850 2647 }
f51e8d7e 2648 echo '<th class="lastpost">'.get_string('lastpost', 'forum').'</th>';
2649 echo '</tr>';
2650 echo '</thead>';
2651 echo '<tbody>';
29507631 2652 }
2653
3335f6fb 2654 foreach ($discussions as $discussion) {
2655 $discussioncount++;
f93f848a 2656
af328e4b 2657 if ($page != -1) { // We are using paging
2658 if ($discussioncount < $pagestart) { // Not there yet
f6bb7eaa 2659 continue;
2660 }
af328e4b 2661 if ($discussioncount > $pageend) { // All done, finish the loop
2662 break;
2663 }
f6bb7eaa 2664 //Without paging, old approach
af328e4b 2665 } else if ($maxdiscussions && ($discussioncount > $maxdiscussions)) {
c20b762a 2666 $olddiscussionlink = true;
3335f6fb 2667 break;
2668 }
e3ff14ca 2669
9c9f7d77 2670 if (!empty($replies[$discussion->discussion])) {
3335f6fb 2671 $discussion->replies = $replies[$discussion->discussion]->replies;
3599e487 2672 $discussion->lastpostid = $replies[$discussion->discussion]->lastpostid;
3335f6fb 2673 } else {
2674 $discussion->replies = 0;
2675 }
af328e4b 2676
f37da850 2677 if ($CFG->forum_trackreadposts) {
489de4ae 2678 /// SPECIAL CASE: The front page can display a news item post to non-logged in users.
2679 /// All posts are read in this case.
2680 if (empty($USER)) {
2681 $discussion->unread = 0;
2682 } else {
1051a2a4 2683 $discussion->unread = forum_tp_count_discussion_unread_posts($USER->id, $discussion->discussion);
489de4ae 2684 }
f37da850 2685 }
2686
f7477444 2687 if (!empty($USER->id)) {
2688 $ownpost = ($discussion->userid == $USER->id);
2689 } else {
2690 $ownpost=false;
2691 }
cf84431b 2692 // Use discussion name instead of subject of first post
2693 $discussion->subject = $discussion->name;
2694
af328e4b 2695 switch ($displayformat) {
2696 case 'header':
3a68fbbb 2697 if ($groupmode > 0) {
2698 if (isset($groups[$discussion->groupid])) {
2699 $group = $groups[$discussion->groupid];
2700 } else {
2701 $group = $groups[$discussion->groupid] = get_record('groups', 'id', $discussion->groupid);
2702 }
2703 } else {
2704 $group = -1;
2705 }
2706 forum_print_discussion_header($discussion, $forum, $group, $strdatestring);
3335f6fb 2707 break;
2708 default:
3260de67 2709 if ($canreply or $discussion->replies) {
2710 $link = true;
2711 } else {
2712 $link = false;
2713 }
f37da850 2714
2715 /// Need to add in the forum id for forum_print_post.
af328e4b 2716 $discussion->forum = $forum->id;
f37da850 2717
af328e4b 2718 forum_print_post($discussion, $course->id, $ownpost, $reply=0, $link, $assessed=false);
3335f6fb 2719 break;
f93f848a 2720 }
2721 }
29507631 2722
af328e4b 2723 if ($displayformat == "header") {
f51e8d7e 2724 echo '</tbody>';
2725 echo '</table>';
29507631 2726 }
c20b762a 2727
2728 if ($olddiscussionlink) {
af328e4b 2729 echo '<div class="forumolddiscuss">';
2730 echo '<a href="'.$CFG->wwwroot.'/mod/forum/view.php?f='.$forum->id.'&amp;showall=1">';
2731 echo get_string('olderdiscussions', 'forum').'</a> ...</div>';
c20b762a 2732 }
f6bb7eaa 2733
c8680d86 2734 if ($page != -1) { ///Show the paging bar
af328e4b 2735 print_paging_bar($numdiscussions, $page, $maxdiscussions, "view.php?f=$forum->id&");
f6bb7eaa 2736 }
f93f848a 2737}
2738
af328e4b 2739
c6d691dc 2740function forum_print_discussion($course, $forum, $discussion, $post, $mode, $canreply=NULL) {
501cdbd8 2741
f37da850 2742 global $USER, $CFG;
501cdbd8 2743
61e96406 2744 if (!empty($USER->id)) {
2745 $ownpost = ($USER->id == $post->userid);
2746 } else {
2747 $ownpost = false;
2748 }
c6d691dc 2749 if ($canreply === NULL) {
2750 $reply = forum_user_can_post($forum);
2751 } else {
2752 $reply = $canreply;
2753 }
501cdbd8 2754
02ebf404 2755 $ratings = NULL;
74f5d1e3 2756 $ratingsmenuused = false;
61e96406 2757 if ($forum->assessed and !empty($USER->id)) {
d6bdd9d5 2758 if ($ratings->scale = make_grades_menu($forum->scale)) {
3bd98ad4 2759 $ratings->assesspublic = $forum->assesspublic;
98914efd 2760 $ratings->assesstimestart = $forum->assesstimestart;
2761 $ratings->assesstimefinish = $forum->assesstimefinish;
0efb3c3d 2762 $ratings->allow = (($forum->assessed != 2 or isteacher($course->id)) && !isguest());
3bd98ad4 2763
0efb3c3d 2764 if ($ratings->allow) {
2765 echo '<form name="form" method="post" action="rate.php">';
2766 echo '<input type="hidden" name="id" value="'.$course->id.'" />';
2767 }
9d1b97c5 2768 }
2769 }
2770
f37da850 2771/// Add the forum id to the post object - used by read tracking.
2772 $post->forum = $forum->id;
2773
2774 if ($CFG->forum_trackreadposts) {
2775 $user_read_array = forum_tp_get_discussion_read_records($USER->id, $post->discussion);
2776 } else {
2777 $user_read_array = array();
2778 }
2779
2780 if (forum_print_post($post, $course->id, $ownpost, $reply, $link=false, $ratings,
2781 '', '', (isset($user_read_array[$post->id]) || forum_tp_is_post_old($post)))) {
74f5d1e3 2782 $ratingsmenuused = true;
2783 }
501cdbd8 2784
2785 switch ($mode) {
2e2e71a8 2786 case FORUM_MODE_FLATOLDEST :
2787 case FORUM_MODE_FLATNEWEST :
65b0e537 2788 default:
f37da850 2789 if (forum_print_posts_flat($post->discussion, $course->id, $mode, $ratings, $reply,
2790 $user_read_array, $post->forum)) {
74f5d1e3 2791 $ratingsmenuused = true;
2792 }
501cdbd8 2793 break;
2794
2e2e71a8 2795 case FORUM_MODE_THREADED :
f37da850 2796 if (forum_print_posts_threaded($post->id, $course->id, 0, $ratings, $reply,
2797 $user_read_array, $post->forum)) {
74f5d1e3 2798 $ratingsmenuused = true;
2799 }
501cdbd8 2800 break;
2801
2e2e71a8 2802 case FORUM_MODE_NESTED :
f37da850 2803 if (forum_print_posts_nested($post->id, $course->id, $ratings, $reply,
2804 $user_read_array, $post->forum)) {
74f5d1e3 2805 $ratingsmenuused = true;
2806 }
501cdbd8 2807 break;
2808 }
2809
74f5d1e3 2810 if ($ratingsmenuused) {
b4510d53 2811 echo "<center><input type=\"submit\" value=\"".get_string("sendinratings", "forum")."\" />";
fa01ae8b 2812 if ($forum->scale < 0) {
2813 if ($scale = get_record("scale", "id", abs($forum->scale))) {
2814 print_scale_menu_helpbutton($course->id, $scale );
2815 }
2816 }
02ebf404 2817 echo "</center>";
2818 echo "</form>";
501cdbd8 2819 }
2820}
2821
f37da850 2822/// Add the forum id to the argument list, for use in 'forum_print_post'.
2823/// Add the user_read_array to the argument list.
83a305a7 2824function forum_print_posts_flat($discussion, $courseid, $direction, $ratings, $reply, &$user_read_array, $forumid=0) {
f37da850 2825 global $USER, $CFG;
501cdbd8 2826
501cdbd8 2827 $link = false;
74f5d1e3 2828 $ratingsmenuused = false;
501cdbd8 2829
2830 if ($direction < 0) {
2831 $sort = "ORDER BY created DESC";
2832 } else {
2833 $sort = "ORDER BY created ASC";
2834 }
2835
1f48942e 2836 if ($posts = forum_get_discussion_posts($discussion, $sort)) {
501cdbd8 2837 foreach ($posts as $post) {
f37da850 2838
2839 /// Add the forum id to the post object - used by read tracking.
2840 if (!$CFG->forum_usermarksread) {
2841 $post->forum = $forumid;
2842 } else {
2843 $post->forum = 0;
2844 }
2845
ebc3bd2b 2846 $ownpost = ($USER->id == $post->userid);
83a305a7 2847 if (forum_print_post($post, $courseid, $ownpost, $reply, $link, $ratings,
f37da850 2848 '', '', (isset($user_read_array[$post->id]) || forum_tp_is_post_old($post)))) {
74f5d1e3 2849 $ratingsmenuused = true;
2850 }
501cdbd8 2851 }
501cdbd8 2852 }
74f5d1e3 2853
2854 return $ratingsmenuused;
501cdbd8 2855}
2856
f37da850 2857/// Add the forum id to the argument list, for use in 'forum_print_post'.
2858/// Add the user_read_array to the argument list.
83a305a7 2859function forum_print_posts_threaded($parent, $courseid, $depth, $ratings, $reply, &$user_read_array, $forumid=0) {
f37da850 2860 global $USER, $CFG;
501cdbd8 2861
501cdbd8 2862 $link = false;
74f5d1e3 2863 $ratingsmenuused = false;
501cdbd8 2864
1f48942e 2865 if ($posts = forum_get_child_posts($parent)) {
501cdbd8 2866 foreach ($posts as $post) {
2867
039c0ec4 2868 echo '<div class="forumpostindent">';
501cdbd8 2869 if ($depth > 0) {
ebc3bd2b 2870 $ownpost = ($USER->id == $post->userid);
f37da850 2871
2872 if (!$CFG->forum_usermarksread) {
2873 $post->forum = $forumid;
2874 } else {
2875 $post->forum = 0;
2876 }
2877
83a305a7 2878 if (forum_print_post($post, $courseid, $ownpost, $reply, $link, $ratings,
f37da850 2879 '', '', (isset($user_read_array[$post->id]) || forum_tp_is_post_old($post)))) {
74f5d1e3 2880 $ratingsmenuused = true;
2881 }
501cdbd8 2882 } else {
83a305a7 2883 $by->name = fullname($post, isteacher($courseid));
d62413e8 2884 $by->date = userdate($post->modified);
f37da850 2885
2886 if ($CFG->forum_trackreadposts) {
2887 if (isset($user_read_array[$post->id]) || forum_tp_is_post_old($post)) {
2888 $style = '<span class="forumthread read">';
2889 } else {
2890 $style = '<span class="forumthread unread">';
2891 }
2892 } else {
2893 $style = '<span class="forumthread">';
2894 }
2895 echo $style."<a name=\"$post->id\"></a>".
2896 "<a href=\"discuss.php?d=$post->discussion&amp;parent=$post->id\">$post->subject</a> ";
8c3c8481 2897 print_string("bynameondate", "forum", $by);
f37da850 2898 echo "</span>";
501cdbd8 2899 }
2900
83a305a7 2901 if (forum_print_posts_threaded($post->id, $courseid, $depth-1, $ratings, $reply,
f37da850 2902 $user_read_array, $forumid)) {
74f5d1e3 2903 $ratingsmenuused = true;
2904 }
bb3b56c6 2905 echo "</div>\n";
501cdbd8 2906 }
501cdbd8 2907 }
74f5d1e3 2908 return $ratingsmenuused;
501cdbd8 2909}
2910
f37da850 2911/// Add the forum id to the argument list, for use in 'forum_print_post'.
2912/// Add the user_read_array to the argument list.
83a305a7 2913function forum_print_posts_nested($parent, $courseid, $ratings, $reply, &$user_read_array, $forumid=0) {
f37da850 2914 global $USER, $CFG;
501cdbd8 2915
501cdbd8 2916 $link = false;
74f5d1e3 2917 $ratingsmenuused = false;
501cdbd8 2918
1f48942e 2919 if ($posts = forum_get_child_posts($parent)) {
501cdbd8 2920 foreach ($posts as $post) {
2921
f37da850 2922 echo '<div class="forumpostindent">';
61e96406 2923 if (empty($USER->id)) {
2924 $ownpost = false;
2925 } else {
2926 $ownpost = ($USER->id == $post->userid);
2927 }
501cdbd8 2928
f37da850 2929 /// Add the forum id to the post object - used by read tracking.
2930 if (!$CFG->forum_usermarksread) {
2931 $post->forum = $forumid;
2932 } else {
2933 $post->forum = 0;
2934 }
2935
83a305a7 2936 if (forum_print_post($post, $courseid, $ownpost, $reply, $link, $ratings,
f37da850 2937 '', '', (isset($user_read_array[$post->id]) || forum_tp_is_post_old($post)))) {
74f5d1e3 2938 $ratingsmenuused = true;
2939 }
83a305a7 2940 if (forum_print_posts_nested($post->id, $courseid, $ratings, $reply, $user_read_array, $forumid)) {
74f5d1e3 2941 $ratingsmenuused = true;
2942 }
bb3b56c6 2943 echo "</div>\n";
501cdbd8 2944 }
501cdbd8 2945 }
74f5d1e3 2946 return $ratingsmenuused;
501cdbd8 2947}
2948
2862b309 2949function forum_get_recent_mod_activity(&$activities, &$index, $sincetime, $courseid, $cmid="0", $user="", $groupid="") {
a57a7794 2950// Returns all forum posts since a given time. If forum is specified then
2951// this restricts the results
2952
2953 global $CFG;
2954
2862b309 2955 if ($cmid) {
2956 $forumselect = " AND cm.id = '$cmid'";
a57a7794 2957 } else {
2958 $forumselect = "";
2959 }
2960
2961 if ($user) {
2962 $userselect = " AND u.id = '$user'";
2963 } else {
2964 $userselect = "";
2965 }
2966
a57a7794 2967 $posts = get_records_sql("SELECT p.*, d.name, u.firstname, u.lastname,
2968 u.picture, d.groupid, cm.instance, f.name, cm.section
2969 FROM {$CFG->prefix}forum_posts p,
2970 {$CFG->prefix}forum_discussions d,
2971 {$CFG->prefix}user u,
2972 {$CFG->prefix}course_modules cm,
2973 {$CFG->prefix}forum f
2974 WHERE p.modified > '$sincetime' $forumselect
2975 AND p.userid = u.id $userselect
2976 AND d.course = '$courseid'
8f0cd6ef 2977 AND p.discussion = d.id
a57a7794 2978 AND cm.instance = f.id
2979 AND cm.course = d.course
2980 AND cm.course = f.course
2981 AND f.id = d.forum
5b257acd 2982 ORDER BY p.discussion ASC,p.created ASC");
a57a7794 2983
2862b309 2984 if (empty($posts)) {
2985 return;
2986 }
2987
2988 $isteacheredit = isteacheredit($courseid);
a57a7794 2989
90708fc1 2990 foreach ($posts as $post) {
a57a7794 2991
2862b309 2992 if ($groupid and ($post->groupid != -1 and $groupid != $post->groupid and !$isteacheredit)) {
2993 continue;
2994 }
a57a7794 2995
2862b309 2996 $tmpactivity->type = "forum";
2997 $tmpactivity->defaultindex = $index;
2998 $tmpactivity->instance = $post->instance;
2999 $tmpactivity->name = $post->name;
3000 $tmpactivity->section = $post->section;
65b0e537 3001
2862b309 3002 $tmpactivity->content->id = $post->id;
3003 $tmpactivity->content->discussion = $post->discussion;
3004 $tmpactivity->content->subject = $post->subject;
3005 $tmpactivity->content->parent = $post->parent;
a57a7794 3006
2862b309 3007 $tmpactivity->user->userid = $post->userid;
3008 $tmpactivity->user->fullname = fullname($post);
3009 $tmpactivity->user->picture = $post->picture;
65b0e537 3010
2862b309 3011 $tmpactivity->timestamp = $post->modified;
3012 $activities[] = $tmpactivity;
3013
3014 $index++;
90708fc1 3015 }
a57a7794 3016
90708fc1 3017 return;
a57a7794 3018}
3019
3020function forum_print_recent_mod_activity($activity, $course, $detail=false) {
3021
d30867b0 3022 global $CFG;
a57a7794 3023
3024 echo '<table border="0" cellpadding="3" cellspacing="0">';
3025
3026 if ($activity->content->parent) {
3027 $openformat = "<font size=\"2\"><i>";
3028 $closeformat = "</i></font>";
3029 } else {
3030 $openformat = "<b>";
3031 $closeformat = "</b>";
3032 }
3033
d30867b0 3034 echo "<tr><td class=\"forumpostpicture\" width=\"35\" valign=\"top\">";
a57a7794 3035 print_user_picture($activity->user->userid, $course, $activity->user->picture);
3036 echo "</td><td>$openformat";
3037
3038 if ($detail) {
3039 echo "<img src=\"$CFG->modpixpath/$activity->type/icon.gif\" ".
839f2456 3040 "height=\"16\" width=\"16\" alt=\"$activity->name\" /> ";
a57a7794 3041 }
3042 echo "<a href=\"$CFG->wwwroot/mod/forum/discuss.php?d=" . $activity->content->discussion
3043 . "#" . $activity->content->id . "\">";
3044
3045 echo $activity->content->subject;
3046 echo "</a>$closeformat";
3047
a9ef4a63 3048 echo "<br /><font size=\"2\">";
839f2456 3049 echo "<a href=\"$CFG->wwwroot/user/view.php?id=" . $activity->user->userid . "&amp;course=" . "$course\">"
a57a7794 3050 . $activity->user->fullname . "</a>";
3051 echo " - " . userdate($activity->timestamp) . "</font></td></tr>";
3052 echo "</table>";
3053
3054 return;
3055}
3056
cf84431b 3057function forum_change_discussionid($postid, $discussionid) {
3058/// recursively sets the discussion field to $discussionid on $postid and all its children
3059/// used when pruning a post
3060 set_field('forum_posts', 'discussion', $discussionid, 'id', $postid);
3061 if ($posts = get_records('forum_posts', 'parent', $postid)) {
3062 foreach ($posts as $post) {
3063 forum_change_discussionid($post->id, $discussionid);
3064 }
3065 }
3066 return true;
3067}
3068
90e7063e 3069function forum_update_subscriptions_button($courseid, $forumid) {
3070// Prints the editing button on subscribers page
3071 global $CFG, $USER;
3072
f88803e0 3073 if (isteacher($courseid)) {
90e7063e 3074 if (!empty($USER->subscriptionsediting)) {
3075 $string = get_string("turneditingoff");
3076 $edit = "off";
3077 } else {
3078 $string = get_string("turneditingon");
3079 $edit = "on";
3080 }
3081 return "<form target=\"$CFG->framename\" method=\"get\" action=\"$CFG->wwwroot/mod/forum/subscribers.php\">".
3082 "<input type=\"hidden\" name=\"id\" value=\"$forumid\" />".
3083 "<input type=\"hidden\" name=\"edit\" value=\"$edit\" />".
3084 "<input type=\"submit\" value=\"$string\" /></form>";
3085 }
3086}
3087
709f0ec8 3088function forum_add_user($userid, $courseid) {
3089/// Add subscriptions for new users
906fef94 3090 if ($forums = get_records_select('forum', "course = '$courseid' AND forcesubscribe = '".FORUM_INITIALSUBSCRIBE."'")) {
709f0ec8 3091 foreach ($forums as $forum) {
3092 forum_subscribe($userid, $forum->id);
3093 }
3094 }
906fef94 3095 if ($forums = get_records_select('forum', "course = '".SITEID."' AND forcesubscribe = '".FORUM_INITIALSUBSCRIBE."'")) {
7b5944cd 3096 foreach ($forums as $forum) {
3097 forum_subscribe($userid, $forum->id);
3098 }
3099 }
709f0ec8 3100}
3101
f37da850 3102function forum_tp_add_read_record($userid, $postid, $discussionid=-1, $forumid=-1) {
3103 if (($readrecord = forum_tp_get_read_records($userid, $postid)) === false) {
3104 /// New read record
3105 unset($readrecord);
3106 $readrecord->userid = $userid;
3107 $readrecord->postid = $postid;
3108 $readrecord->discussionid = $discussionid;
3109 $readrecord->forumid = $forumid;
3110 $readrecord->firstread = time();
3111 $readrecord->lastread = $readrecord->firstread;
90fd2b51 3112 return insert_record('forum_read', $readrecord, true);
f37da850 3113 }
3114 else {
3115 /// Update read record
3116 $readrecord = reset($readrecord);
3117 $readrecord->lastread = time();
3118
3119 /// This shouldn't happen, but just in case...
3120 if (!$readrecord->firstread) {
3121 $readrecord->firstread = $readrecord->lastread;
3122 /// Update the 'firstread' field.
3123 set_field('forum_read', 'firstread', $readrecord->firstread, 'userid', $userid, 'postid', $postid);
3124 }
3125 if ($discussionid > -1) {
3126 /// Update the 'discussionid' field.
3127 set_field('forum_read', 'discussionid', $discussionid, 'userid', $userid, 'postid', $postid);
3128 }
3129 if ($forumid > -1) {
3130 /// Update the 'forumid' field.
3131 set_field('forum_read', 'forumid', $forumid, 'userid', $userid, 'postid', $postid);
3132 }
3133
3134 $readrecord->forumid = $forumid;
3135 /// Update the 'lastread' field.
3136 return set_field('forum_read', 'lastread', $readrecord->lastread, 'userid', $userid, 'postid', $postid);
3137 }
3138}
3139
3140function forum_tp_get_read_records($userid=-1, $postid=-1, $discussionid=-1, $forumid=-1) {
3141 /// Returns all records in the 'forum_read' table matching the passed keys, indexed
3142 /// by userid.
3143 $select = '';
3144 if ($userid > -1) {
3145 if ($select != '') $select .= ' AND ';
3146 $select .= 'userid = \''.$userid.'\'';
3147 }
3148 if ($postid > -1) {
3149 if ($select != '') $select .= ' AND ';
3150 $select .= 'postid = \''.$postid.'\'';
3151 }
3152 if ($discussionid > -1) {
3153 if ($select != '') $select .= ' AND ';
3154 $select .= 'discussionid = \''.$discussionid.'\'';
3155 }
3156 if ($forumid > -1) {
3157 if ($select != '') $select .= ' AND ';
3158 $select .= 'forumid = \''.$forumid.'\'';
3159 }
3160
3161 return get_records_select('forum_read', $select);
3162}
3163
3164function forum_tp_get_discussion_read_records($userid, $discussionid) {
3165 /// Returns all read records for the provided user and discussion, indexed by postid.
3166 $select = 'userid = \''.$userid.'\' AND discussionid = \''.$discussionid.'\'';