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