Index: moodle/lang/en_utf8/forum.php =================================================================== RCS file: /Users/John/Documents/JWC/Moodle 1.9.4 CVS/moodle 1.9.4/moodle/lang/en_utf8/forum.php,v retrieving revision 1.1.1.1 diff -u -r1.1.1.1 forum.php --- moodle/lang/en_utf8/forum.php 31 Jan 2009 08:06:42 -0000 1.1.1.1 +++ moodle/lang/en_utf8/forum.php 21 Feb 2009 00:55:19 -0000 @@ -1,5 +1,6 @@ -
If you wish to DELETE all such subscriptions, click Yes
You will then need to save the forum settings again.

Otherwise click No'; $string['forum'] = 'Forum'; $string['forum:addnews'] = 'Add news'; $string['forumauthorhidden'] = 'Author (hidden)'; @@ -174,7 +187,7 @@ $string['noviewdiscussionspermission'] = 'You do not have the permission to view discussions in this forum'; $string['nowallsubscribed'] = 'All forums in $a are subscribed.'; $string['nowallunsubscribed'] = 'All forums in $a are not subscribed.'; -$string['nownotsubscribed'] = '$a->name will NOT receive copies of \'$a->forum\' by email.'; +$string['nownotsubscribed'] = '$a->name will NOT receive email copies of all posts to \'$a->forum\''; $string['nownottracking'] = '$a->name is no longer tracking \'$a->forum\'.'; $string['nowsubscribed'] = '$a->name will receive copies of \'$a->forum\' by email.'; $string['nowtracking'] = '$a->name is now tracking \'$a->forum\'.'; @@ -219,6 +232,8 @@ $string['ratingpublic'] = '$a can see everyone\'s ratings'; $string['ratingpublicnot'] = '$a can only see their own ratings'; $string['ratings'] = 'Ratings'; +$string['ratingsnudge'] = 'Remind user to rate posts'; +$string['ratingsreminder'] = 'Reminder:

We notice that you began this discussion thread, and other users have contributed to it, however, you have not rated any of these postings as yet. You may wish to rate postings now or return later to do so, if you prefer.

You can use the navigation \'breadcrumb\' trail, or the back button, to leave this discussion.'; $string['ratingssaved'] = 'Ratings saved'; $string['ratingsuse'] = 'Use ratings'; $string['ratingtime'] = 'Restrict ratings to posts with dates in this range:'; @@ -254,18 +269,33 @@ $string['seeallposts'] = 'See all posts made by this user'; $string['sendinratings'] = 'Send in my latest ratings'; $string['shortpost'] = 'Short post'; -$string['showsubscribers'] = 'Show/edit current subscribers'; +$string['showsubscribers'] = 'Show/edit current forum subscribers'; $string['singleforum'] = 'A single simple discussion'; $string['startedby'] = 'Started by'; $string['subject'] = 'Subject'; $string['subscribe'] = 'Subscribe to this forum'; $string['subscribeall'] = 'Subscribe everyone to this forum'; $string['subscribed'] = 'Subscribed'; +$string['subscribedfirst'] = 'Subscribed threads are shown first'; +$string['subscribedfirstclick'] = 'CLICK to show subscribed threads first'; +$string['subscribedfirstgo'] = 'Show subscribed threads first'; +$string['subscribedmixed'] = 'Threads are shown in date order'; +$string['subscribedmixedclick'] = 'CLICK to show threads in date order'; +$string['subscribedmixedgo'] = 'Show threads in date order'; +$string['subscribedq'] = 'Subscribed?'; +$string['subscribedthread'] = 'You are subscribed to this discussion thread'; +$string['subscribedthreadno'] = 'You are NOT subscribed to this discussion thread'; +$string['subscribedthreadq'] = 'Thread subscribed?'; $string['subscribenone'] = 'Unsubscribe everyone from this forum'; $string['subscribers'] = 'Subscribers'; $string['subscribersto'] = 'Subscribers to \'$a\''; $string['subscribestart'] = 'Send me email copies of posts to this forum'; +$string['subscribestartthread'] = 'Send me email copies of posts to this discussion'; +$string['subscribestartthreadclick'] = 'CLICK to ALLOW emails from this discussion'; $string['subscribestop'] = 'I don\'t want email copies of posts to this forum'; +$string['subscribestopthread'] = 'I don\'t want email copies of posts to this discussion'; +$string['subscribestopthreadclick'] = 'CLICK to DISALLOW emails from this discussion'; +$string['subscribethisthread'] = 'Subscribe to this discussion thread'; $string['subscription'] = 'Subscription'; $string['subscriptions'] = 'Subscriptions'; $string['thisforumisthrottled'] = 'This forum has a limit to the number of forum postings you can make in a given time period - this is currently set at $a->blockafter posting(s) in $a->blockperiod'; @@ -288,7 +318,10 @@ $string['unsubscribeallempty'] = 'Sorry, you are not subscribed to any forums. If you do not want to receive any emails from this server please go to your profile and disable email address there.'; $string['unsubscribed'] = 'Unsubscribed'; $string['unsubscribeshort'] = 'Unsubscribe'; +$string['unsubscribethisthread'] = 'Unsubscribe from this discussion thread'; $string['usermarksread'] = 'Manual message read marking'; +$string['userunsubscribewarning'] = 'You are currently subscribed to one or more discussion threads in this forum!

If you wish to DELETE all such subscriptions so as to replace these with a subscription to the entire forum, click Yes.

Otherwise click No.'; +$string['warnofthreadsubs'] = 'WARNING: $a thread subscription(s) already exist in this forum!
The number of such subscriptions appear in parenthesis after the user\'s name.
Subscribing a user to the forum WILL REMOVE any thread subscriptions they had!'; $string['warnafter'] = 'Post threshold for warning'; $string['yesforever'] = 'Yes, forever'; $string['yesinitially'] = 'Yes, initially'; Index: moodle/lang/en_utf8/help/forum/subscription.html =================================================================== RCS file: /Users/John/Documents/JWC/Moodle 1.9.4 CVS/moodle 1.9.4/moodle/lang/en_utf8/help/forum/subscription.html,v retrieving revision 1.1.1.1 diff -u -r1.1.1.1 subscription.html --- moodle/lang/en_utf8/help/forum/subscription.html 6 Jan 2007 11:00:58 -0000 1.1.1.1 +++ moodle/lang/en_utf8/help/forum/subscription.html 13 Feb 2009 19:08:37 -0000 @@ -16,3 +16,7 @@ towards the beginning of the course (before everyone has worked out that they can subscribe to these emails themselves).

+

Further choices may be offered by the teacher allowing +subscription by discussion thread. When subscribed to a thread +the user gets email copies of posts in that thread only. +In very large forums this may be more appropriate.

\ No newline at end of file Index: moodle/lang/en_utf8/help/forum/subscription2.html =================================================================== RCS file: /Users/John/Documents/JWC/Moodle 1.9.4 CVS/moodle 1.9.4/moodle/lang/en_utf8/help/forum/subscription2.html,v retrieving revision 1.1.1.1 diff -u -r1.1.1.1 subscription2.html --- moodle/lang/en_utf8/help/forum/subscription2.html 6 Jan 2007 11:00:58 -0000 1.1.1.1 +++ moodle/lang/en_utf8/help/forum/subscription2.html 13 Feb 2009 19:08:46 -0000 @@ -31,5 +31,4 @@ existing users, it will only affect future course users. Similarly changing later to "Yes, initially" will not subscribe existing course users but only those enrolling later. -

- +

\ No newline at end of file Index: moodle/mod/forum/discuss.php =================================================================== RCS file: /Users/John/Documents/JWC/Moodle 1.9.4 CVS/moodle 1.9.4/moodle/mod/forum/discuss.php,v retrieving revision 1.1.1.1 diff -u -r1.1.1.1 discuss.php --- moodle/mod/forum/discuss.php 29 Jan 2009 08:07:20 -0000 1.1.1.1 +++ moodle/mod/forum/discuss.php 19 Feb 2009 16:59:03 -0000 @@ -1,4 +1,4 @@ -id, 'id', $discussion->id); set_field('forum_read', 'forumid', $forumto->id, 'discussionid', $discussion->id); + $modcontextto = get_context_instance(CONTEXT_MODULE, $cmto->id); + forum_discussion_copy_subscribers($discussion->id, $forum->id, $discussion->id, $forumto->id, $modcontextto); add_to_log($course->id, 'forum', 'move discussion', "discuss.php?d=$discussion->id", $discussion->id, $cmto->id); require_once($CFG->libdir.'/rsslib.php'); @@ -165,8 +168,15 @@ /// Print the controls across the top - echo ''; @@ -3153,8 +3361,18 @@ // User name $fullname = fullname($post, has_capability('moodle/site:viewfullnames', $modcontext)); + + // Added to show count of postings to forums (within a course) by user, if forum_countposts is set + if (empty($CFG->forum_countposts)) { + $postcount = ''; + } else { + $sql = 'SELECT COUNT(*) FROM '.$CFG->prefix.'forum_discussions fd, '.$CFG->prefix . + 'forum_posts fp WHERE fd.id=fp.discussion AND fd.course='.$forum->course.' AND fp.userid='.$postuser->id; + $postcount = ' ('.count_records_sql($sql).')'; + } + echo '\n"; // Group picture @@ -3203,7 +3421,15 @@ echo "\n"; } } - + // Edit for thread subscriptions : Add Subscribed yes/no button to thread summaries where needed + if ((has_capability('mod/forum:initialsubscriptions', $modcontext) || + has_capability('mod/forum:managesubscriptions', $modcontext)) && + forum_is_subscription_to_threads_allowed($USER->id, $forum)) { + echo ''; + } + // End of edit echo '\n"; @@ -4015,10 +4251,16 @@ forum_tp_delete_read_records(-1, -1, $discussion->id); + // Added for thread subscriptions : delete discussion, so delete all user subscriptions to it + // largely redundant as these are removed in recursion of forum_delete_post() + if (! forum_unsubscribe_all_from_thread($forumid, $discussion->id)) { + $result = false; + } + if (! delete_records("forum_discussions", "id", "$discussion->id")) { $result = false; } - + return $result; } @@ -4036,6 +4278,10 @@ return false; } } + + // Added for thread-based suscriptions + forum_unsubscribe_user_post($post); + if (delete_records("forum_posts", "id", $post->id)) { delete_records("forum_ratings", "post", $post->id); // Just in case @@ -4048,8 +4294,14 @@ forum_delete_old_attachments($post); } - // Just in case we are deleting the last post + // Just in case we are deleting the last post forum_discussion_update_last_post($post->discussion); + + // Added line for thread-based subscriptions... if last post has gone + // be sure to clean out thread subscriptions + if (! count_records('forum_posts', 'discussion', $post->discussion)) { + forum_unsubscribe_all_from_thread($post->forum, $post->discussion); + } return true; } @@ -4105,15 +4357,77 @@ if (forum_is_forcesubscribed($forum)) { return true; } - return record_exists("forum_subscriptions", "userid", $userid, "forum", $forum->id); + // Edit for thread subscriptions : change record_exists call for one that tests for thread=0 + // so as not to confuse with thread subscriptions + $where = " userid='$userid' AND forum='$forum->id' AND thread=0"; + return record_exists_select("forum_subscriptions", $where); +} + +/** + * Function added for thread subscriptions : returns true if subscribed AT LEAST by thread + */ +function forum_is_subscribed_to_thread($userid, $forum, $threadid=-1) { + if (is_numeric($forum)) { + $forum = get_record('forum', 'id', $forum); + } + if (forum_is_forcesubscribed($forum)) { + return true; + } + if ($threadid < 0) { + // If $threadid is -1 returns existence of ANY of this user's thread-based subscriptions only + $where = " userid='$userid' AND forum='$forum->id' AND thread<>0"; + } else { + // If $threadid > 0 returns existence of this thread or the forum subscription + $where = " userid='$userid' AND forum='$forum->id' AND (thread='$threadid' OR thread=0)"; + } + return record_exists_select("forum_subscriptions", $where); +} + + +/** + * Function added for thread subscriptions : returns number of subscriptions to a thread + */ +function forum_count_thread_subscriptions($userid, $forumid, $threadid=-1) { + // If $threadid=-1 counts all a users thread subscriptions in this forum, but don't count thread=0 + // otherwise count specific thread => 0 or 1 + + global $CFG; + + $sql = 'SELECT COUNT(*) FROM '.$CFG->prefix.'forum_subscriptions WHERE userid='.$userid.' AND forum='.$forumid + . ($threadid == -1 ? ' AND thread > 0' : ' AND thread='.$threadid); + + return count_records_sql($sql); +} + + +/** + * Function added for thread subscriptions : returns true if subscribed by thread is allowed (by forum) + * and sensible (for user) + */ +function forum_is_subscription_to_threads_allowed($userid, $forum) { + if (is_numeric($forum)) { + $forum = get_record('forum', 'id', $forum); + } + switch ($forum->forcesubscribe) { + case FORUM_ALLOWTHREADSUBSCRIBE: + case FORUM_AUTOTHREADSUBSCRIBE: + case FORUM_FORCETHREADSUBSCRIBE: + return (empty($userid)?true:!forum_is_subscribed($userid, $forum)); + break; + default: + return false; + } + return true; } function forum_get_subscribed_forums($course) { + // Edited for thread subscriptions : addition of 'AND fs.thread=0' to leave out thread subscriptions global $USER, $CFG; $sql = "SELECT f.id FROM {$CFG->prefix}forum f LEFT JOIN {$CFG->prefix}forum_subscriptions fs ON (fs.forum = f.id AND fs.userid = $USER->id) WHERE f.forcesubscribe <> ".FORUM_DISALLOWSUBSCRIBE." + AND fs.thread=0 AND (f.forcesubscribe = ".FORUM_FORCESUBSCRIBE." OR fs.id IS NOT NULL)"; if ($subscribed = get_records_sql($sql)) { foreach ($subscribed as $s) { @@ -4129,36 +4443,143 @@ * Adds user to the subscriber list */ function forum_subscribe($userid, $forumid) { - - if (record_exists("forum_subscriptions", "userid", $userid, "forum", $forumid)) { + if (record_exists("forum_subscriptions", "userid", $userid, "forum", $forumid, "thread", "0")) { return true; } - + // Edit for thread subscriptions : remove thread-based subscriptions as redundant (note: no need for thread test here) + delete_records("forum_subscriptions", "userid", $userid, "forum", $forumid); + // End of edit : note 'thread'=0 by default below $sub = new object(); $sub->userid = $userid; $sub->forum = $forumid; - return insert_record("forum_subscriptions", $sub); } /** * Removes user from the subscriber list + * Edit for thread-based subscriptions... modified to only remove FORUM subscription if $thread=0 */ -function forum_unsubscribe($userid, $forumid) { +function forum_unsubscribe($userid, $forumid, $thread=-1) { + // Note for thread subscriptions: Unsubscribe from forum threaded or otherwise! + // ...but if thread subscriptions are to be left intact then use condition thread=0 + if ($thread == 0) { + return delete_records("forum_subscriptions", "userid", $userid, "forum", $forumid, "thread", 0); + } return delete_records("forum_subscriptions", "userid", $userid, "forum", $forumid); } /** + * Removes all from the subscriber list + * Added for thread-based subscriptions... also to clear possible bug in original + */ +function forum_unsubscribe_all($forumid) { + // Note for thread subscriptions: Unsubscribe all from forum threaded or otherwise! + return delete_records("forum_subscriptions", "forum", $forumid); +} + +/** + * Adds user subscription to forum thread + * Added for thread-based subscriptions + */ +function forum_subscribe_thread($userid, $forumid, $threadid) { + if (record_exists("forum_subscriptions", "userid", $userid, "forum", $forumid, "thread", $threadid)) { + return true; + } + // Insert new record if record for this user/forum/thread doesn't exist + $sub = new object(); + $sub->userid = $userid; + $sub->forum = $forumid; + $sub->thread = $threadid; + return insert_record("forum_subscriptions", $sub); +} + +/** + * Removes user subscription to forum thread + * Added for thread-based subscriptions + */ +function forum_unsubscribe_thread($userid, $forumid, $threadid) { + // Remove only record for this user/forum/thread + $where = " userid='$userid' AND forum='$forumid' AND thread=$threadid"; + return delete_records_select("forum_subscriptions", $where); +} + +/** + * Removes all user subscriptions to forum thread + * Added for thread-based subscriptions + */ +function forum_unsubscribe_all_from_thread($forumid, $threadid) { + // Remove only records for all users in this thread + $where = " forum='$forumid' AND thread=$threadid"; + return delete_records_select("forum_subscriptions", $where); +} + +/** + * Removes user subscription to thread if only one post to thread is about to be deleted + * Added for thread-based subscriptions + */ +function forum_unsubscribe_user_post($post) { + // Added for thread subscriptions : Remove only record for this user/forum/thread + // Deletion of relevant thread subscription if only this post left, for this user, in this discussion + // $post must arrive with ->forum entry + global $CFG; + + $sql = "SELECT COUNT(*) FROM " . $CFG->prefix . "forum_posts WHERE discussion='{$post->discussion}' AND userid='{$post->userid}'"; + $count = count_records_sql($sql); + if ($count == 1) { + return forum_unsubscribe_thread($post->userid, $post->forum, $post->discussion); + } + return 0; +} + +/** + * Generates alert action for user unsubscribing from thread they began without rating contributed posts + * Added for thread-based subscriptions + */ +function forum_alert_unsubscribing_user($userid, $forumid, $threadid) { + global $CFG; + + $alert = 0; + // Offer reminder about rating a forum if ratings allowed and the unsubscribing user was the discussion originator + // Users nested conditions to lighten load for majority of cases + if (!empty($CFG->forum_ratingsnudge)) { + // if we are required to nudge unsubscribing user + $forum = get_record('forum', 'id', $forumid); + if (!empty($forum->assessed)) { + // if this forum allows ratings + $discussion = get_record('forum_discussions', 'id', $threadid); + if ($discussion->userid == $userid) { + // if this discussion was started by this user + $sql = 'SELECT COUNT(*) FROM '.$CFG->prefix.'forum_posts WHERE discussion='.$threadid.' AND userid<>'.$userid; + $count = count_records_sql($sql); + if (!empty($count)) { + // if there are posts to this thread from other users + $sql = 'SELECT COUNT(*) FROM '.$CFG->prefix.'forum_posts fp, '.$CFG->prefix.'forum_ratings fr WHERE fp.id=fr.post AND fp.discussion=' . + $threadid. ' AND fr.userid='.$userid; + $count = count_records_sql($sql); + if (empty($count)) { + // if not even one post to this thread has been rated by this user issue warning + $alert = 1; + } + } + } + } + } + return $alert; +} + +/** * Given a new post, subscribes or unsubscribes as appropriate. * Returns some text which describes what happened. */ -function forum_post_subscription($post, $forum) { - +function forum_post_subscription($post, $forum, $threadid=0) { + // Edited for thread-based subscriptions global $USER; - $action = ''; $subscribed = forum_is_subscribed($USER->id, $forum); - + $info = new object(); + $info->name = fullname($USER); + $info->forum = format_string($forum->name); + if ($forum->forcesubscribe == FORUM_FORCESUBSCRIBE) { // database ignored return ""; @@ -4170,34 +4591,56 @@ return ""; } - } else { // go with the user's choice + } elseif ($forum->forcesubscribe == FORUM_FORCETHREADSUBSCRIBE) { + forum_unsubscribe($USER->id, $forum->id); + $info->thread = $threadid; + forum_subscribe_thread($USER->id, $forum->id, $threadid); + return "

".get_string("nowsubscribed", "forum", $info)."

"; + + } else { // go with the user's choice, or pre-set to FORUM_SUBSCRIBE_THREAD_START if (isset($post->subscribe)) { - // no change - if ((!empty($post->subscribe) && $subscribed) - || (empty($post->subscribe) && !$subscribed)) { - return ""; - - } elseif (!empty($post->subscribe) && !$subscribed) { - $action = 'subscribe'; - - } elseif (empty($post->subscribe) && $subscribed) { - $action = 'unsubscribe'; + switch($post->subscribe) { + case FORUM_SUBSCRIBE_STOP: + // No change - do nothing + if (!$subscribed) return ""; + // else unsubscribe + forum_unsubscribe($USER->id, $forum->id); + return "

".get_string("nownotsubscribed", "forum", $info)."

"; + break; + + case FORUM_SUBSCRIBE_START: + // No change - do nothing + if ($subscribed) return ""; + // else subscribe + forum_subscribe($USER->id, $forum->id); + return "

".get_string("nowsubscribed", "forum", $info)."

"; + break; + + case FORUM_SUBSCRIBE_THREAD_STOP: + // If subscribed to forum, unsubscribing from thread is irrelevant! + if ($subscribed) return ""; + // else unsubscribe from thread + $info->thread = $threadid; + forum_unsubscribe_thread($USER->id, $forum->id, $threadid); + return "

".get_string("nownotsubscribed", "forum", $info)."

"; + break; + + case FORUM_SUBSCRIBE_THREAD_START: + // If subscribed to forum, subscribing from thread adds nothing! + // But if pre-subscribed to forum, and forum forces auto-thread + // subscription then there needs to be a get-out clause: + if ($forum->forcesubscribe == FORUM_FORCETHREADSUBSCRIBE) { + forum_unsubscribe($USER->id, $forum->id); + $subscribed = false; + } + if ($subscribed) return ""; + // else subscribe to thread + $info->thread = $threadid; + forum_subscribe_thread($USER->id, $forum->id, $threadid); + return "

".get_string("nowsubscribed", "forum", $info)."

"; } } } - - $info = new object(); - $info->name = fullname($USER); - $info->forum = format_string($forum->name); - - switch ($action) { - case 'subscribe': - forum_subscribe($USER->id, $post->forum); - return "

".get_string("nowsubscribed", "forum", $info)."

"; - case 'unsubscribe': - forum_unsubscribe($USER->id, $post->forum); - return "

".get_string("nownotsubscribed", "forum", $info)."

"; - } } /** @@ -4225,6 +4668,8 @@ return $messages['forcesubscribed']; } else if ($forum->forcesubscribe == FORUM_DISALLOWSUBSCRIBE && !has_capability('mod/forum:managesubscriptions', $context)) { return $messages['cantsubscribe']; + } else if ($forum->forcesubscribe == FORUM_FORCETHREADSUBSCRIBE && $fakelink) { + return ' '; } else if ($cantaccessagroup) { return $messages['cantaccessgroup']; } else { @@ -4274,6 +4719,149 @@ } } +/** + * Generate and return the subscribe or unsubscribe link for a forum. + * @param object $forum the forum. Fields used are $forum->id and $forum->forcesubscribe. + * @param object $context the context object for this forum. + * @param value $threadid the thread id in this forum. + * @param boolean $buttoned switches on/off button style link. + * @param boolean $backtoindex switches return action. + * + * Function added for thread subscriptions modelled on forum_get_subscribe_link() + * + */ +function forum_get_subscribe_thread_link($forum, $context, $threadid, $buttoned=true, $backtoindex=false) { + // Test validity of subscription linking BEFORE entering this function + global $CFG, $USER; + $messages = array( + 'button_yes' => get_string('yes'), + 'button_no' => get_string('no'), + 'subscribe' => get_string('subscribethisthread', 'forum'), + 'unsubscribe' => get_string('unsubscribethisthread', 'forum'), + 'start' => get_string('subscribestartthreadclick', 'forum'), + 'stop' => get_string('subscribestopthreadclick', 'forum'), + 'enforced' => get_string('forcesthreadsubs', 'forum'), + 'subscribed' => get_string('subscribedthread', 'forum'), + 'unsubscribed' => get_string('subscribedthreadno', 'forum') + ); + + $subscribed = forum_is_subscribed_to_thread($USER->id, $forum, $threadid); + $subscribe = !$subscribed; + + if ($forum->forcesubscribe == FORUM_FORCETHREADSUBSCRIBE) { + if ($buttoned) { + return($subscribed?$messages['button_yes']:$messages['button_no']); + } else { + return($messages['enforced']. '
'. ($subscribed?$messages['subscribed']:$messages['unsubscribed'])); + } + } + + if ($buttoned) { + if ($subscribed) { + $linktext = $messages['button_yes']; + $linktitle = $messages['stop']; + } else { + $linktext = $messages['button_no']; + $linktitle = $messages['start']; + } + } else { + if ($subscribed) { + $linktext = $messages['unsubscribe']; + $linktitle = $messages['stop']; + } else { + $linktext = $messages['subscribe']; + $linktitle = $messages['start']; + } + } + + $options = array(); + if ($backtoindex) { + $backtoindexlink = '&backtoindex=1'; + $options['backtoindex'] = 1; + } else { + $backtoindexlink = ''; + } + + $link = ''; + + // We need to separate the buttoned and none buttoned links but supply non script versions in both cases, + // however AJAX will only appear on the buttoned versions, and a non-script version needs to exist here too. + if ($buttoned) { + // use javascript to supply AJAX link if allowed + $options['id'] = $forum->id; + $options['thread'] = $threadid; + $options['subscribe'] = $subscribe; + $div = '_'.$threadid; + if (ajaxenabled() && !empty($CFG->forum_ajaxrating)) { + // AJAX enabled, so don't use print_single_button because it contains it's own form + // No need to send forumid (done for whole form), or threadid (recovered from submit button id) + // ...so we only require subscribe state and submit button, and both must be uniquely labelled + // But problem occurs when both are enabled but Javascript is turned off in browser! + $link .= ''; + } else { + // No AJAX, so use ordinary VIM! + $link .= print_single_button($CFG->wwwroot . '/mod/forum/subscribe.php', $options, $linktext, 'post', '_self', true, $linktitle); + } + } else { + // but if not 'buttoned' use javascript to rewrite link + $address = '&address=discuss'; + $options['id'] = $forum->id; + $options['thread'] = $threadid; + $options['subscribe'] = $subscribe; + $options['address'] = 'discuss'; + $link .= << +//wwwroot/mod/forum/subscribe.php?id={$forum->id}&thread={$threadid}&subscribe={$subscribe}{$address}{$backtoindexlink}'>$linktext<\/a>"; +} +//]]> + +'; + } + + return $link; +} + +/** + * Added for thread-based subscriptions + * Generate and return the link for ordering discussions with/without subscribed threads first. + * @param object $forum the forum. + */ + function forum_get_order($forumid, $order) { + + global $CFG; + + $messages = array( + 'first' => get_string('subscribedfirstgo', 'forum'), + 'mixed' => get_string('subscribedmixedgo', 'forum'), + 'firstclick' => get_string('subscribedfirstclick', 'forum'), + 'mixedclick' => get_string('subscribedmixedclick', 'forum') + ); + + $order = ($order == 1)? 0 : 1; + + if ($order) { + $linktext = $messages['first']; + $linktitle = $messages['firstclick']; + } else { + $linktext = $messages['mixed']; + $linktitle = $messages['mixedclick']; + } + + $options = array(); + $options['order'] = $order; + $link = print_single_button($CFG->wwwroot . '/mod/forum/view.php?f=' . $forumid, $options, $linktext, 'post', '_self', true, $linktitle); + + return $link; +} /** * Generate and return the track or no track link for a forum. @@ -4669,7 +5257,7 @@ * */ function forum_print_latest_discussions($course, $forum, $maxdiscussions=-1, $displayformat='plain', $sort='', - $currentgroup=-1, $groupmode=-1, $page=-1, $perpage=100, $cm=NULL) { + $currentgroup=-1, $groupmode=-1, $page=-1, $perpage=100, $cm=NULL, $order=0) { global $CFG, $USER; if (!$cm) { @@ -4752,7 +5340,16 @@ } } -// Get all the recent discussions we're allowed to see + // Added for thread-based subscriptions AJAX control + // 'ajaxform' will only run AJAX if this is correctly enabled + // But (amendment 2009.02.22) this form must not exist without AJAX enabled + echo "\n"; + if (!empty($CFG->forum_ajaxrating)) { + echo '
'; + echo ''; + } + + // Get all the recent discussions we're allowed to see $getuserlastmodified = ($displayformat == 'header'); @@ -4809,6 +5406,31 @@ } if ($displayformat == 'header') { + + // Added for thread-based subscriptions, and ordering therof, $order=0 or not set in single discussions + if ($order == 1) { + foreach ($discussions as $k=>$d) { + $yesno_count = forum_count_thread_subscriptions($USER->id, $forum->id, $d->discussion); + $discussions[$k]->yesno = (($yesno_count>0) ? 1 : 0); + } + /* Now re-sort $discussions! + * This may not be the SPEEDIEST method, although this sort will only be called if the user chooses the order subscribed threads first. + * However, as records are already in 'timemodified' order, this requires only a minimal bubble sort to float subscribed threads to top. + * Other possibilities include running a significantly modified query when getting $discussions, to patch the above COUNT(*) into the sql, + * but this too will have significant overheads as the table forum_subscriptions is not matched 1:1 with forum_discussions, naturally. + * A third possibility (likely to be faster than either of the above) is to change the foreach ($discussions as $discussion) loop (BELOW) + * for a loop of 2 x count($discussions) passes, in which every discussion is printed if yesno=1 in the first count($discussions) passes, + * and every discussion is printed if yesno=0 in the second count($discussions) passes. + * When $order=0, the yesno field is not added (above), and is threfore not tested in the passes, and the loop bails out after only + * count($discussions) passes. + * A refinement of this double-pass process is to count the number of yesno=1 cases, so as to jump to the half-way mark when those cases + * have been printed, and in the second half end when the balance have been printed - though this latter action is probably unwarranted. + * TODO: Choose which of these 3 methods is likely to be most rapid in most cases, especially very large cases. + */ + usort($discussions, "compare_yesno"); + } + // End of addition + echo '
'; - + echo ''; + // Edit for thread subscriptions + echo '\n"; + echo '
'; + if ((has_capability('mod/forum:initialsubscriptions', $modcontext) || + has_capability('mod/forum:managesubscriptions', $modcontext)) && + forum_is_subscription_to_threads_allowed($USER->id, $forum)) { + echo '
', forum_get_subscribe_thread_link($forum, $context, $discussion->id, FALSE, FALSE), '
'; + } + echo '
'; // groups selector not needed here echo ""; @@ -211,6 +221,14 @@ } } } + // Moved up from below + $canrate = has_capability('mod/forum:rate', $modcontext); + + // Added for thread-based subscriptions and alert to unsubscribing discussion originator + if ($alert && $canrate ) { + echo "

'.get_string('ratingsreminder', 'forum').'
'; + } echo "
"; if (!empty($forum->blockafter) && !empty($forum->blockperiod)) { @@ -228,8 +246,7 @@ if ($move == -1 and confirm_sesskey()) { notify(get_string('discussionmoved', 'forum', format_string($forum->name,true))); } - - $canrate = has_capability('mod/forum:rate', $modcontext); + forum_print_discussion($course, $cm, $forum, $discussion, $post, $displaymode, $canreply, $canrate); print_footer($course); Index: moodle/mod/forum/index.php =================================================================== RCS file: /Users/John/Documents/JWC/Moodle 1.9.4 CVS/moodle 1.9.4/moodle/mod/forum/index.php,v retrieving revision 1.1.1.1 diff -u -r1.1.1.1 index.php --- moodle/mod/forum/index.php 8 Oct 2008 08:20:48 -0000 1.1.1.1 +++ moodle/mod/forum/index.php 13 Feb 2009 19:09:01 -0000 @@ -1,4 +1,4 @@ -libdir.'/filelib.php'); @@ -12,6 +13,16 @@ define('FORUM_FORCESUBSCRIBE', 1); define('FORUM_INITIALSUBSCRIBE', 2); define('FORUM_DISALLOWSUBSCRIBE',3); +define('FORUM_ALLOWTHREADSUBSCRIBE',4); +define('FORUM_AUTOTHREADSUBSCRIBE',5); +define('FORUM_FORCETHREADSUBSCRIBE',6); +/* Note: (Option 6) If users are pre-subscribed to forum, +their first post sets them to forced thread subscription */ + +define ('FORUM_SUBSCRIBE_STOP', 0); +define ('FORUM_SUBSCRIBE_START', 1); +define ('FORUM_SUBSCRIBE_THREAD_STOP', 2); +define ('FORUM_SUBSCRIBE_THREAD_START', 3); define('FORUM_TRACKING_OFF', 0); define('FORUM_TRACKING_OPTIONAL', 1); @@ -246,7 +257,8 @@ $timenow = time(); $endtime = $timenow - $CFG->maxeditingtime; $starttime = $endtime - 48 * 3600; // Two days earlier - + + mtrace(' '); if ($posts = forum_get_unmailed_posts($starttime, $endtime, $timenow)) { // Mark them all now as being mailed. It's unlikely but possible there // might be an error later so that a post is NOT actually mailed out, @@ -295,17 +307,16 @@ if ($cm = get_coursemodule_from_instance('forum', $forumid, $courseid)) { $coursemodules[$forumid] = $cm; } else { - mtrace('Could not course module for forum '.$forumid); + mtrace('Could not find course module for forum '.$forumid); unset($posts[$pid]); continue; } } - - + // caching subscribed users of each forum if (!isset($subscribedusers[$forumid])) { $modcontext = get_context_instance(CONTEXT_MODULE, $coursemodules[$forumid]->id); - if ($subusers = forum_subscribed_users($courses[$courseid], $forums[$forumid], 0, $modcontext)) { + if ($subusers = forum_subscribed_users($courses[$courseid], $forums[$forumid], 0, $modcontext, false)) { foreach ($subusers as $postuser) { // do not try to mail users with stopped email if ($postuser->emailstop) { @@ -314,18 +325,47 @@ } continue; } - // this user is subscribed to this forum - $subscribedusers[$forumid][$postuser->id] = $postuser->id; + // Edit for thread subscriptions : now holds thread=0 for all threads + // this user is subscribed to this forum (or thread) + $subscribedusers[$forumid][$postuser->id][0] = $postuser->id; // this user is a user we have to process later $users[$postuser->id] = $postuser; + mtrace('user: '.$postuser->id.', forum: '.$forumid.', discussions: all'); } unset($subusers); // release memory } } - + // Added for thread subscriptions : now get user subscriptions to threads, add users if not already in $users array + // This must not be trapped within: if (!isset($subscribedusers[$forumid])), so if does not collect + // greedy user data except for users not already in $users array. + if (! forum_is_forcesubscribed($forum)) { + // Irrelevant if forum force-subscribed (Admin can't benefit here from thread subscription in forced forum!) + // Groups currently ignored here + // Any users in $users array cannot have emailstop set! + if ($subusersids = forum_subscribed_users_threads($forumid, $discussionid, 0)) { + foreach ($subusersids as $postuserid) { + if (!isset($users[$postuserid->id])) { + $postuser = forum_get_subscribed_user($postuserid->id); + if (isset($postuser[$postuserid->id])) { + $users[$postuserid->id] = $postuser[$postuserid->id]; + } + } + $subscribedusers[$forumid][$postuserid->id][$discussionid] = $postuserid->id; + mtrace('user: '.$postuserid->id.', forum: '.$forumid.', discussion: '.$discussionid.', post: '.$pid); + } + unset($subusersids); // release memory (though not the issue it is above) + } + } + + $mailcount[$pid] = 0; $errorcount[$pid] = 0; } + // Thread subscriptions : ksort will mean that mtrace will put entries into cron.php in userid order + // As the trace does not show the email addresses this seems more logical than ORDER BY u.email + // in forum_subscribed_users (some conditions). $sort parameter now removes sorting in the sql. + // Remove if speed is preferred over order in the cron. Email order immaterial! + ksort($users); } if ($users && $posts) { @@ -364,7 +404,8 @@ $cm =& $coursemodules[$forum->id]; // Do some checks to see if we can bail out now - if (!isset($subscribedusers[$forum->id][$userto->id])) { + // Thread subscriptions : now checks thread id or thread=0 for all threads + if (!(isset($subscribedusers[$forum->id][$userto->id][0]) || isset($subscribedusers[$forum->id][$userto->id][$post->discussion]))) { continue; // user does not subscribe to this forum } @@ -380,7 +421,8 @@ // Get info about the sending user if (array_key_exists($post->userid, $users)) { // we might know him/her already $userfrom = $users[$post->userid]; - } else if ($userfrom = get_record('user', 'id', $post->userid)) { + } else if ($userfrom = forum_get_subscribed_user($post->userid)) { + // Thread subscriptions : small edit to collect selective records using forum_get_subscribed_user(), not all using get_record() $users[$userfrom->id] = $userfrom; // fetch only once, we can add it to user list, it will be skipped anyway } else { mtrace('Could not find user '.$post->userid); @@ -923,9 +965,15 @@ $posthtml .= forum_make_mail_post($course, $forum, $discussion, $post, $userfrom, $userto, false, $canreply, true, false); if ($canunsubscribe) { - $posthtml .= '
'; + $posthtml .= '
'; } $posthtml .= ''; @@ -2316,7 +2364,7 @@ if (empty($forumsort)) { - $forumsort = "d.timemodified DESC"; + $forumsort = "d.timemodified DESC"; //xxxx } if (empty($fullpost)) { $postdata = "p.id,p.subject,p.modified,p.discussion,p.userid"; @@ -2332,6 +2380,11 @@ $umtable = " LEFT JOIN {$CFG->prefix}user um ON (d.usermodified = um.id)"; } + // Added for thread-based subscriptions, requires possible change of sort order + if (forum_is_subscription_to_threads_allowed($USER->id, $forum)) { + + } + $sql = "SELECT $postdata, d.name, d.timemodified, d.usermodified, d.groupid, d.timestart, d.timeend, u.firstname, u.lastname, u.email, u.picture, u.imagealt $umfields FROM {$CFG->prefix}forum_discussions d @@ -2486,6 +2539,25 @@ ORDER BY p.created DESC"); } + +/** + * Added for thread-based suscriptions + * Get forum id from data provided at forum post + */ +function forum_get_post_forumid($forumid, $replyid, $editid) { + // if one of these three is set we should be able to get forumid + Global $CFG; + + if (empty($forumid)) { + // not an original post, try reply or edit + $postid = (!empty($replyid) ? $replyid : (!empty($editid) ? $editid : 0)); + $sql = 'SELECT forum FROM '.$CFG->prefix.'forum_posts fp, '.$CFG->prefix.'forum_discussions fd WHERE fp.discussion=fd.id AND fp.id='.$postid; + $rcs = get_record_sql($sql); + $forumid = $rcs->forum; + } + return $forumid; +} + /** * Get the list of potential subscribers to a forum. * @@ -2508,7 +2580,7 @@ * @param object $context the forum context, to save re-fetching it where possible. * @return array list of users. */ -function forum_subscribed_users($course, $forum, $groupid=0, $context = NULL) { +function forum_subscribed_users($course, $forum, $groupid=0, $context = NULL, $sort=true) { global $CFG; if ($groupid) { @@ -2520,15 +2592,22 @@ $groupselect = ''; } + if ($sort) { + $sortorder = "u.email ASC"; + $orderby = " ORDER BY u.email ASC"; + } else { + $sortorder = ""; + $orderby = ""; + } + if (forum_is_forcesubscribed($forum)) { if (empty($context)) { $cm = get_coursemodule_from_instance('forum', $forum->id, $course->id); $context = get_context_instance(CONTEXT_MODULE, $cm->id); } - $sort = "u.email ASC"; $fields ="u.id, u.username, u.firstname, u.lastname, u.maildisplay, u.mailformat, u.maildigest, u.emailstop, u.imagealt, u.email, u.city, u.country, u.lastaccess, u.lastlogin, u.picture, u.timezone, u.theme, u.lang, u.trackforums, u.mnethostid"; - $results = forum_get_potential_subscribers($context, $groupid, $fields, $sort); + $results = forum_get_potential_subscribers($context, $groupid, $fields, $sortorder); } else { $results = get_records_sql("SELECT u.id, u.username, u.firstname, u.lastname, u.maildisplay, u.mailformat, u.maildigest, u.emailstop, u.imagealt, u.email, u.city, u.country, u.lastaccess, u.lastlogin, u.picture, u.timezone, u.theme, u.lang, u.trackforums, u.mnethostid @@ -2536,8 +2615,9 @@ {$CFG->prefix}forum_subscriptions s $grouptables WHERE s.forum = '$forum->id' AND s.userid = u.id + AND s.thread = 0 AND u.deleted = 0 $groupselect - ORDER BY u.email ASC"); + $orderby "); } static $guestid = null; @@ -2556,6 +2636,124 @@ return $results; } +/** + * Function added for thread subscriptions, as forum-user-thread would have multiple + * instances of user in a forum based heavily on forum_subscribed_users() + * Returns list of users who are subscribed by forum or thread + */ +function forum_subscribed_users_threads($forumid, $thread, $groupid=0) { + // Test for forum_is_forcesubscribed($forum) before entry + global $CFG; + + if ($groupid) { + $grouptables = ", {$CFG->prefix}groups_members gm "; + $groupselect = "AND gm.groupid = $groupid AND u.id = gm.userid"; + + } else { + $grouptables = ''; + $groupselect = ''; + } + + $sql = "SELECT u.id FROM {$CFG->prefix}user u, {$CFG->prefix}forum_subscriptions s $grouptables + WHERE s.forum = '{$forumid}' AND s.userid = u.id AND s.thread = '{$thread}' AND u.deleted = 0 $groupselect"; + //mtrace($sql); + $results = get_records_sql($sql); + + static $guestid = null; + + if (is_null($guestid)) { + if ($guest = guest_user()) { + $guestid = $guest->id; + } else { + $guestid = 0; + } + } + + // Guest user should never be subscribed to a forum. + unset($results[$guestid]); + + return $results; +} + +/** + * Function added for thread subscriptions, as to get information as forum_subscribed_users() + * but for a single user + * Returns list of users who are subscribed by forum or thread + */ +function forum_get_subscribed_user($userid) { + + global $CFG; + + $sql = "SELECT id, username, firstname, lastname, maildisplay, mailformat, maildigest, emailstop, imagealt, email, city, country, + lastaccess, lastlogin, picture, timezone, theme, lang, trackforums, mnethostid + FROM {$CFG->prefix}user WHERE id = '{$userid}' AND deleted = 0"; + $results = get_records_sql($sql); + + static $guestid = null; + + if (is_null($guestid)) { + if ($guest = guest_user()) { + $guestid = $guest->id; + } else { + $guestid = 0; + } + } + + // Guest user should never be subscribed to a forum. + unset($results[$guestid]); + + return $results; +} + +/** + * Function added for thread subscriptions, copy subscriptions for discussions from original + * thread to new discussion created by 'split' + */ +function forum_discussion_copy_subscribers($thread, $forumid, $newthread, $newforumid=NULL, $newcontext=NULL) { + // No need to check on subscriptions to new thread because there cannot be any + // Nor should there by subscriptions to whole forum as well as thread for 'split', + // but there may be for 'move' + global $CFG; + + $sql = "SELECT userid FROM {$CFG->prefix}forum_subscriptions + WHERE forum={$forumid} AND thread={$thread}"; + + if ($subscribers = get_records_sql($sql)) { + $data = new object(); + if (!isset($newforumid)) { + // Not a new forum so this is a 'split' + // Copy all exisint subscriptions from this thread to the new one + foreach ($subscribers as $subscriber) { + $data->userid = $subscriber->userid; + $data->forum = $forumid; + $data->thread = $newthread; + insert_record('forum_subscriptions', $data); + } + } else { + // This will be a new forum so this is a 'move' so + // remove all subscriptions to this thread in the donor forum. + forum_unsubscribe_all_from_thread($forumid, $thread); + // Check for whether thread subscriptions will be allowed in new forum, + // whether each user is allowed be subscribed there, (both initialsubscriptions + // and managesubscriptions have been used here to leave you only total non-subscribers), + // and whether the user is already subscribed to the forum as a whole. + if (forum_is_subscription_to_threads_allowed(0, $newforumid)) { + foreach ($subscribers as $subscriber) { + if (has_capability('mod/forum:initialsubscriptions', $newcontext, $subscriber->userid) || + has_capability('mod/forum:managesubscriptions', $newcontext, $subscriber->userid)) { + if (!forum_is_subscribed($subscriber->userid, $newforumid)) { + $data->userid = $subscriber->userid; + $data->forum = $newforumid; + $data->thread = $newthread; + insert_record('forum_subscriptions', $data); + } + } + } + } + } + } +} + // OTHER FUNCTIONS /////////////////////////////////////////////////////////// @@ -2876,9 +3074,19 @@ echo '
'; $fullname = fullname($postuser, $cm->cache->caps['moodle/site:viewfullnames']); + + // Added to show count of postings to forums (within a course) by user, if forum_countposts is set + if (empty($CFG->forum_countposts)) { + $postcount = ''; + } else { + $sql = 'SELECT COUNT(*) FROM '.$CFG->prefix.'forum_discussions fd, '.$CFG->prefix . + 'forum_posts fp WHERE fd.id=fp.discussion AND fd.course='.$forum->course.' AND fp.userid='.$postuser->id; + $postcount = ' ('.count_records_sql($sql).')'; + } + $by = new object(); $by->name = ''.$fullname.''; + $post->userid.'&course='.$course->id.'">'.$fullname.$postcount.''; $by->date = userdate($post->modified); print_string('bynameondate', 'forum', $by); echo '
'; - echo ''.$fullname.''; + echo ''.$fullname.$postcount.''; echo "'; + echo ''; + echo ''; $usedate = (empty($post->timemodified)) ? $post->modified : $post->timemodified; // Just in case $parenturl = (empty($post->lastpostid)) ? '' : '&parent='.$post->lastpostid; @@ -3211,8 +3437,18 @@ $usermodified->id = $post->usermodified; $usermodified->firstname = $post->umfirstname; $usermodified->lastname = $post->umlastname; + + // Added to show count of postings to forums (within a course) by user, if forum_countposts is set + if (empty($CFG->forum_countposts)) { + $postcount = ''; + } else { + $sql = 'SELECT COUNT(*) FROM '.$CFG->prefix.'forum_discussions fd, '.$CFG->prefix . + 'forum_posts fp WHERE fd.id=fp.discussion AND fd.course='.$forum->course.' AND fp.userid='.$usermodified->id; + $postcount = ' ('.count_records_sql($sql).')'; + } + echo ''. - fullname($usermodified).'
'; + fullname($usermodified).$postcount.'
'; echo ''. userdate($usedate, $datestring).''; echo "
'; echo ''; echo ''; @@ -4830,6 +5452,14 @@ } echo ''; } + // Edit for thread subscriptions : table header for thread subscriptions + // Is there a more appropriate and complete permission to use? + if ((has_capability('mod/forum:initialsubscriptions', $context) || + has_capability('mod/forum:managesubscriptions', $context)) && + forum_is_subscription_to_threads_allowed($USER->id, $forum)) { + echo ''; + } + } echo ''; echo ''; @@ -4878,6 +5508,7 @@ } else { $group = -1; } + // Function edited for thread-based subscriptions forum_print_discussion_header($discussion, $forum, $group, $strdatestring, $cantrack, $forumtracked, $canviewparticipants, $context); break; @@ -4902,6 +5533,26 @@ echo ''; echo '
'.get_string('subscribedthreadq', 'forum').''.get_string('lastpost', 'forum').'
'; } + + // Added for thread-based subscriptions AJAX control + // But (amendment 2009.02.22) this form must not exist without AJAX enabled + if (!empty($CFG->forum_ajaxrating)) { + echo ''; + } + + if (ajaxenabled() && !empty($CFG->forum_ajaxrating)) { + // AJAX enabled, create submission form for yesno script + // but not unless AJAX enabled as false button will show + echo '
'; + echo ''; + $yesno_ajax_config_settings = array("pixpath"=>$CFG->pixpath, "wwwroot"=>$CFG->wwwroot, "sesskey"=>sesskey()); + echo "\n"; + echo "
\n"; + } + if ($olddiscussionlink) { if ($forum->type == 'news') { @@ -4919,6 +5570,21 @@ } } +/** + * Specific comparison function for sorting discussions + */ +function compare_yesno($a, $b) { + // Reverse sort on yesno & timemodified + if ($a->yesno == $b->yesno) { + if ($a->timemodified == $b->timemodified) { + return 0; + } else { + return ($a->timemodified < $b->timemodified) ? 1 : -1; + } + } else { + return ($a->yesno < $b->yesno) ? 1 : -1; + } +} /** * @@ -5045,7 +5711,7 @@ if ($ratingsformused) { if ($ratingsmenuused) { - echo '
'; + echo '
'; echo ''; if (ajaxenabled() && !empty($CFG->forum_ajaxrating)) { /// AJAX enabled, standard submission form $rate_ajax_config_settings = array("pixpath"=>$CFG->pixpath, "wwwroot"=>$CFG->wwwroot, "sesskey"=>sesskey()); Index: moodle/mod/forum/mod_form.php =================================================================== RCS file: /Users/John/Documents/JWC/Moodle 1.9.4 CVS/moodle 1.9.4/moodle/mod/forum/mod_form.php,v retrieving revision 1.1.1.1 diff -u -r1.1.1.1 mod_form.php --- moodle/mod/forum/mod_form.php 27 Jul 2008 08:17:58 -0000 1.1.1.1 +++ moodle/mod/forum/mod_form.php 20 Feb 2009 14:59:21 -0000 @@ -1,4 +1,6 @@ dirroot.'/course/moodleform_mod.php'); class mod_forum_mod_form extends moodleform_mod { @@ -34,12 +36,16 @@ $options = array(); $options[0] = get_string('no'); - $options[1] = get_string('yesforever', 'forum'); + $options[FORUM_FORCESUBSCRIBE] = get_string('yesforever', 'forum'); $options[FORUM_INITIALSUBSCRIBE] = get_string('yesinitially', 'forum'); $options[FORUM_DISALLOWSUBSCRIBE] = get_string('disallowsubscribe','forum'); + // Edit for thread subscriptions, settings 4,5,6 + $options[FORUM_ALLOWTHREADSUBSCRIBE] = get_string('allowthreadsubs','forum'); + $options[FORUM_AUTOTHREADSUBSCRIBE] = get_string('autothreadsubs','forum'); + $options[FORUM_FORCETHREADSUBSCRIBE] = get_string('forcethreadsubs','forum'); $mform->addElement('select', 'forcesubscribe', get_string('forcesubscribeq', 'forum'), $options); $mform->setHelpButton('forcesubscribe', array('subscription2', get_string('forcesubscribeq', 'forum'), 'forum')); - + $options = array(); $options[FORUM_TRACKING_OPTIONAL] = get_string('trackingoptional', 'forum'); $options[FORUM_TRACKING_OFF] = get_string('trackingoff', 'forum'); @@ -164,6 +170,24 @@ $type->freeze(); $type->setPersistantFreeze(true); } + + // Added for thread-based subscriptions, after choosing FORUM_DISALLOWSUBSCRIBE... + // If 'Yes' delete all user subscriptions then return to form to save setting + $forcesubscribe = $mform->getElement('forcesubscribe'); + $force = $_GET["force"]; + if (isset($force)) { + $forcesubscribe->setValue($force); + } + // Added for thread-based subscriptions. + // Has there previously been a bug that lets mail through to one-time subscribers + // even after forum has switched to FORUM_DISALLOWSUBSCRIBE??? + // Remove all forum subscriptions if $force = FORUM_DISALLOWSUBSCRIBE + if ($force == FORUM_DISALLOWSUBSCRIBE) { + $inst = $mform->getElementValue('instance'); + if ($forum = get_record("forum", "id", $inst)) { + forum_unsubscribe_all($forum->id); + } + } } @@ -178,7 +202,39 @@ $default_values['ratingtime']= ($default_values['assesstimestart'] && $default_values['assesstimefinish']) ? 1 : 0; } + } + + + // Added for thread-based subscriptions : additional form verification to warn if subscriptions will be removed + function validation($data, $files) { + + global $CFG; + + $errors = parent::validation($data, $files); + + // No need to check on subscriptions if setting is not FORUM_DISALLOWSUBSCRIBE + if ($data['forcesubscribe'] != FORUM_DISALLOWSUBSCRIBE) { + // exit validating all settings + return $errors; + } + + $sql = "SELECT id FROM {$CFG->prefix}forum_subscriptions WHERE forum='{$data['instance']}'"; + + if (count_records_sql($sql)) { + // If under threat of user subscription removal... + print_header_simple(""); + notice_yesno(get_string("forceunsubscribewarning", "forum"), + $CFG->wwwroot."/course/modedit.php?update=".$data['coursemodule']. + "&force=".FORUM_DISALLOWSUBSCRIBE."&return=1", + $CFG->wwwroot."/mod/forum/view.php?id=".$data['coursemodule']); + print_footer($course); + die; + } + + return $errors; + } + } ?> Index: moodle/mod/forum/post.php =================================================================== RCS file: /Users/John/Documents/JWC/Moodle 1.9.4 CVS/moodle 1.9.4/moodle/mod/forum/post.php,v retrieving revision 1.1.1.1 diff -u -r1.1.1.1 post.php --- moodle/mod/forum/post.php 15 Jan 2009 08:07:02 -0000 1.1.1.1 +++ moodle/mod/forum/post.php 13 Feb 2009 19:10:20 -0000 @@ -1,4 +1,5 @@ -id, $newid); // update last post in each discussion - forum_discussion_update_last_post($discussion->id); + forum_discussion_update_last_post($discussion->forum, $discussion->id); forum_discussion_update_last_post($newid); + // Added for thread subscriptions : copy all subscriptions for old discussion over to new discussion + forum_discussion_copy_subscribers($discussion->id, $discussion->forum, $newid); add_to_log($discussion->course, "forum", "prune post", "discuss.php?d=$newid", "$post->id", $cm->id); @@ -507,8 +510,9 @@ $timemessage = 4; } $message .= '
'.get_string("postupdated", "forum"); - - if ($subscribemessage = forum_post_subscription($fromform, $forum)) { + + // Edit for thread subscriptions : added $realpost->discussion to parameters + if ($subscribemessage = forum_post_subscription($fromform, $forum, $realpost->discussion)) { $timemessage = 4; } if ($forum->type == 'single') { @@ -539,7 +543,8 @@ $timemessage = 4; } - if ($subscribemessage = forum_post_subscription($fromform, $forum)) { + // Edit for thread subscriptions : added $fromform->discussion to parameters + if ($subscribemessage = forum_post_subscription($fromform, $forum, $fromform->discussion)) { $timemessage = 4; } @@ -608,7 +613,8 @@ $message .= '

'.get_string("postaddedtimeleft", "forum", format_time($CFG->maxeditingtime)) . '

'; } - if ($subscribemessage = forum_post_subscription($discussion, $forum)) { + // Edit for thread subscriptions : added $discussion->id to parameters + if ($subscribemessage = forum_post_subscription($discussion, $forum, $discussion->id)) { $timemessage = 4; } @@ -736,23 +742,27 @@ } //load data into form - if (forum_is_subscribed($USER->id, $forum->id)) { $subscribe = true; - + // Added for thread subscriptions : Default state 1 + $opt = 1; } else if (forum_user_has_posted($forum->id, 0, $USER->id)) { $subscribe = false; - + // Added for thread subscriptions : Allow states 0, 2 or 3 based on settings + $opt = forum_is_subscription_to_threads_allowed($USER->id, $forum)?(($forum->forcesubscribe == FORUM_AUTOTHREADSUBSCRIBE || $forum->forcesubscribe == FORUM_FORCETHREADSUBSCRIBE)?3:(!empty($USER->autosubscribe)?3:2)):0; } else { // user not posted yet - use subscription default specified in profile $subscribe = !empty($USER->autosubscribe); + // Added for thread subscriptions : Allow states 0, 1, 2, or 3 based on settings + $opt = forum_is_subscription_to_threads_allowed($USER->id, $forum)?(($forum->forcesubscribe == FORUM_AUTOTHREADSUBSCRIBE || $forum->forcesubscribe == FORUM_FORCETHREADSUBSCRIBE)?3:$subscribe?3:2):($subscribe?1:0); } // HACK ALERT: this is very wrong, the defaults should be always initialized before calling $mform->get_data() !!! + // Edit for thread subscriptions : $opt replaces $subscribe?1:0 in array settings $mform_post->set_data(array( 'general'=>$heading, 'subject'=>$post->subject, 'message'=>$post->message, - 'subscribe'=>$subscribe?1:0, + 'subscribe'=>$opt, 'mailnow'=>!empty($post->mailnow), 'userid'=>$post->userid, 'parent'=>$post->parent, Index: moodle/mod/forum/post_form.php =================================================================== RCS file: /Users/John/Documents/JWC/Moodle 1.9.4 CVS/moodle 1.9.4/moodle/mod/forum/post_form.php,v retrieving revision 1.1.1.1 diff -u -r1.1.1.1 post_form.php --- moodle/mod/forum/post_form.php 19 Jul 2008 08:17:50 -0000 1.1.1.1 +++ moodle/mod/forum/post_form.php 21 Feb 2009 10:49:37 -0000 @@ -1,4 +1,5 @@ -libdir.'/formslib.php'); @@ -6,7 +7,7 @@ function definition() { - global $CFG; + global $CFG, $USER; $mform =& $this->_form; $course = $this->_customdata['course']; @@ -41,12 +42,23 @@ $mform->addElement('hidden', 'subscribe'); $mform->setHelpButton('subscribemessage', array('subscription', get_string('subscription', 'forum'), 'forum')); + } else if ($forum->forcesubscribe == FORUM_FORCETHREADSUBSCRIBE) { + + $mform->addElement('static', 'subscribemessage', get_string('subscription', 'forum'), get_string('forcesthreadsubs', 'forum')); + $mform->addElement('hidden', 'subscribe'); + $mform->setHelpButton('subscribemessage', array('subscription', get_string('subscription', 'forum'), 'forum')); + } else if (isset($forum->forcesubscribe)&& $forum->forcesubscribe != FORUM_DISALLOWSUBSCRIBE || has_capability('moodle/course:manageactivities', $coursecontext)) { $options = array(); - $options[0] = get_string('subscribestop', 'forum'); - $options[1] = get_string('subscribestart', 'forum'); + $options[FORUM_SUBSCRIBE_STOP] = get_string('subscribestop', 'forum'); + $options[FORUM_SUBSCRIBE_START] = get_string('subscribestart', 'forum'); + // Added for thread subscriptions : additional options for thread subscription + if (forum_is_subscription_to_threads_allowed($USER->id, $forum)) { + $options[FORUM_SUBSCRIBE_THREAD_STOP] = get_string('subscribestopthread', 'forum'); + $options[FORUM_SUBSCRIBE_THREAD_START] = get_string('subscribestartthread', 'forum'); + } $mform->addElement('select', 'subscribe', get_string('subscription', 'forum'), $options); $mform->setHelpButton('subscribe', array('subscription', get_string('subscription', 'forum'), 'forum')); @@ -128,12 +140,95 @@ } + // Added for thread-based subscriptions. + // Remove all forum subscriptions if $force=1 implies FORUM_SUBSCRIBE_STOP or FORUM_SUBSCRIBE_START + function definition_after_data(){ + parent::definition_after_data(); + $mform =& $this->_form; + $type =& $mform->getElement('type'); + $typevalue = $mform->getElementValue('type'); + + global $CFG, $USER; + + $scribe = $mform->getElement('subscribe'); + $subscribe = $mform->getElementValue('subscribe'); + + foreach($_SESSION['SESSION']->post as $k=>$d) { + if ($item = $mform->getElement($k)) { + $item->setValue($d); + // echo ($mform->getElementValue($k)); + } + } + + // If 'Yes' delete this users subscriptions then return to form to save setting + $force = $_GET["force"]; + if (!empty($force)) { + // If we are being 'forced' to remove thread subscriptions then... + $subscribe = empty($_SESSION['SESSION']->post['subscribe']) ? 0 : 1; + + // Get forum id from post data + $forumid = forum_get_post_forumid($mform->getElementValue('forum'), $mform->getElementValue('reply'), $mform->getElementValue('edit')); + + // Remove all forum subscriptions if $force implies FORUM_SUBSCRIBE_STOP or FORUM_SUBSCRIBE_START + if ($forum = get_record("forum", "id", $forumid)) { + forum_unsubscribe($USER->id, $forumid); + } + } + // Store the value $subscribe back in element 'subscribe', + // whether this be the value from post.php or the value from the session as forced + $scribe->setValue($subscribe); + // release memory from cookie store + unset($_SESSION['SESSION']->post); + } + + function validation($data, $files) { $errors = parent::validation($data, $files); if (($data['timeend']!=0) && ($data['timestart']!=0) && $data['timeend'] <= $data['timestart']) { - $errors['timeend'] = get_string('timestartenderror', 'forum'); - } + $errors['timeend'] = get_string('timestartenderror', 'forum'); + } + + // Added for thread-based subscriptions : additional form verification to warn if subscriptions will be removed + + global $CFG, $USER; + // No need to check on subscriptions unless setting is FORUM_SUBSCRIBE_STOP/START + switch ($data['subscribe']) { + case FORUM_SUBSCRIBE_STOP: + case FORUM_SUBSCRIBE_START: + + // Get forum id from post data + $forumid = forum_get_post_forumid($data['forum'], $data['reply'], $data['edit']); + + if (! $forum = get_record("forum", "id", $forumid)) { + error("Forum ID was incorrect or no longer exists"); + } + + $sql = 'SELECT id FROM '.$CFG->prefix.'forum_subscriptions WHERE forum='.$forum->id.' AND userid='.$USER->id.' AND thread<>0'; + + if (count_records_sql($sql)) { + // If under threat of user subscription removal... + $_SESSION['SESSION']->post = array(); + foreach($data as $k=>$d) { + if (!empty($d)) { + $_SESSION['SESSION']->post[$k] = $d; + } + } + + print_header_simple(""); + notice_yesno(get_string("userunsubscribewarning", "forum"), + $_SERVER['HTTP_REFERER'] . "&force=1", + $_SERVER['HTTP_REFERER']); + print_footer($course); + die; + } + break; + + default: + // exit validating all settings + return $errors; + } + return $errors; } Index: moodle/mod/forum/settings.php =================================================================== RCS file: /Users/John/Documents/JWC/Moodle 1.9.4 CVS/moodle 1.9.4/moodle/mod/forum/settings.php,v retrieving revision 1.1.1.1 diff -u -r1.1.1.1 settings.php --- moodle/mod/forum/settings.php 18 Jan 2009 08:05:10 -0000 1.1.1.1 +++ moodle/mod/forum/settings.php 20 Feb 2009 13:48:12 -0000 @@ -1,4 +1,4 @@ -dirroot.'/mod/forum/lib.php'); @@ -61,6 +61,12 @@ $settings->add(new admin_setting_configcheckbox('forum_logblocked', get_string('logblocked', 'forum'), get_string('configlogblocked', 'forum'), 1)); +$settings->add(new admin_setting_configcheckbox('forum_countposts', get_string('countposts', 'forum'), + get_string('configcountposts', 'forum'), 0)); + +$settings->add(new admin_setting_configcheckbox('forum_ratingsnudge', get_string('ratingsnudge', 'forum'), + get_string('configratingsnudge', 'forum'), 0)); + $settings->add(new admin_setting_configcheckbox('forum_ajaxrating', get_string('ajaxrating', 'forum'), get_string('configajaxrating', 'forum'), 0)); Index: moodle/mod/forum/subscribe.php =================================================================== RCS file: /Users/John/Documents/JWC/Moodle 1.9.4 CVS/moodle 1.9.4/moodle/mod/forum/subscribe.php,v retrieving revision 1.1.1.1 diff -u -r1.1.1.1 subscribe.php --- moodle/mod/forum/subscribe.php 14 Apr 2008 08:16:58 -0000 1.1.1.1 +++ moodle/mod/forum/subscribe.php 21 Feb 2009 14:14:51 -0000 @@ -1,4 +1,5 @@ -id : "view.php?f=$id"; + // Edit for thread subscriptions to add in 'autothread' if ($force and has_capability('mod/forum:managesubscriptions', $context)) { - if (forum_is_forcesubscribed($forum)) { - forum_forcesubscribe($forum->id, 0); - redirect($returnto, get_string("everyonecannowchoose", "forum"), 1); - } else { - forum_forcesubscribe($forum->id, 1); - redirect($returnto, get_string("everyoneisnowsubscribed", "forum"), 1); + switch($force) { + case 'no': + forum_forcesubscribe($forum->id, 0); + redirect($returnto, get_string("everyonecannowchoose", "forum"), 1); + break; + case 'yes': + forum_forcesubscribe($forum->id, FORUM_FORCESUBSCRIBE); + redirect($returnto, get_string("everyoneisnowsubscribed", "forum"), 1); + break; + case 'autothread': + forum_forcesubscribe($forum->id, FORUM_AUTOTHREADSUBSCRIBE); + redirect($returnto, get_string("autothreadsubscribed", "forum"), 1); } } + // Added for thread subscriptions for subscription by discussion thread + if ($thread and (has_capability('mod/forum:initialsubscriptions', $context) || + has_capability('mod/forum:managesubscriptions', $context))) { + // Use a 'soft' permission here to make sure the button/link works if it exists in the first + // place, but should this use 'mod/forum:viewdiscussion'? + // Should this just be if ($thread) ? + $alert = 0; + switch($subscribe) { + case 0: + if (has_capability('mod/forum:rate', $context)) { + $alert = forum_alert_unsubscribing_user($USER->id, $forum->id, $thread); + // $alert==1 if thread originator is unsubscribing without rating when this is expected + } + forum_unsubscribe_thread($user->id, $forum->id, $thread); + if (!empty($alert)) { + // remove option to go back to view.php or index.php, and add alert message + redirect("discuss.php?d=".$thread."&alert=1", get_string("subscribedthreadno", "forum"), 5); + } + redirect(($address=="discuss"?"discuss.php?d=".$thread:$returnto), get_string("subscribedthreadno", "forum"), 1); + break; + case 1: + forum_subscribe_thread($user->id, $forum->id, $thread); + redirect(($address=="discuss"?"discuss.php?d=".$thread:$returnto), get_string("subscribedthread", "forum"), 1); + } + } + if (forum_is_forcesubscribed($forum)) { redirect($returnto, get_string("everyoneisnowsubscribed", "forum"), 1); } @@ -97,6 +137,24 @@ if (!has_capability('mod/forum:viewdiscussion', $context)) { error("Could not subscribe you to that forum", $_SERVER["HTTP_REFERER"]); } + // + if ($wipe) { + // Remove user's subscriptions, as this will remove threaded subscriptions + // User has accepted warning hence $wipe. + forum_unsubscribe($userid, $forumid); + } else { + // Check if this means losing user's thread subscriptions, and give warning + if (forum_is_subscribed_to_thread($user->id, $forum->id)) { + print_header_simple(""); + notice_yesno(get_string("userunsubscribewarning", "forum"), + "subscribe.php?id=".$forum->id."&backtoindex=".$backtoindex."&wipe=1", + $returnto); + + print_footer($course); + die; + } + } + if (forum_subscribe($user->id, $forum->id) ) { add_to_log($course->id, "forum", "subscribe", "view.php?f=$forum->id", $forum->id, $cm->id); redirect($returnto, get_string("nowsubscribed", "forum", $info), 1); Index: moodle/mod/forum/subscriber.html =================================================================== RCS file: /Users/John/Documents/JWC/Moodle 1.9.4 CVS/moodle 1.9.4/moodle/mod/forum/subscriber.html,v retrieving revision 1.1.1.1 diff -u -r1.1.1.1 subscriber.html --- moodle/mod/forum/subscriber.html 12 Dec 2008 08:03:32 -0000 1.1.1.1 +++ moodle/mod/forum/subscriber.html 15 Feb 2009 00:02:45 -0000 @@ -3,6 +3,11 @@ + + + @@ -42,14 +47,16 @@ echo "\n"; foreach ($searchusers as $user) { $fullname = fullname($user, true); - echo "\n"; + $tag = ($user->threadssubscribed == 0) ? '' : ' ('.$user->threadssubscribed.')'; + echo "\n"; } echo "\n"; } if (!empty($users)) { foreach ($users as $user) { $fullname = fullname($user, true); - echo "\n"; + $tag = ($user->threadssubscribed == 0) ? '' : ' ('.$user->threadssubscribed.')'; + echo "\n"; } } ?> Index: moodle/mod/forum/subscribers.php =================================================================== RCS file: /Users/John/Documents/JWC/Moodle 1.9.4 CVS/moodle 1.9.4/moodle/mod/forum/subscribers.php,v retrieving revision 1.1.1.1 diff -u -r1.1.1.1 subscribers.php --- moodle/mod/forum/subscribers.php 12 Dec 2008 08:03:32 -0000 1.1.1.1 +++ moodle/mod/forum/subscribers.php 18 Feb 2009 16:19:04 -0000 @@ -1,4 +1,4 @@ -remove) and !empty($frm->removeselect)) { foreach ($frm->removeselect as $removesubscriber) { - if (! forum_unsubscribe($removesubscriber, $id)) { + if (! forum_unsubscribe($removesubscriber, $id, 0)) { error("Could not remove subscriber with id $removesubscriber from this forum!"); } } @@ -121,6 +121,15 @@ /// Get all the potential subscribers excluding users already subscribed $users = forum_get_potential_subscribers($context, $currentgroup, 'id,email,firstname,lastname', 'firstname ASC, lastname ASC'); +/// Added for thread-based subscriptions: in 'threadsubscribed' to $user array + $sub_count = 0; + foreach ($users as $k=>$u) { + $users[$k]->threadssubscribed = forum_count_thread_subscriptions($u->id, $forum->id); + // Note: It should not matter aggregrating thread count from 'subscribers' as these must all be zero. + $sub_count += $users[$k]->threadssubscribed; + } + $warningmessage = ($sub_count > 0) ? get_string('warnofthreadsubs', 'forum', $sub_count) : ''; + if (!$users) { $users = array(); } Index: moodle/mod/forum/view.php =================================================================== RCS file: /Users/John/Documents/JWC/Moodle 1.9.4 CVS/moodle 1.9.4/moodle/mod/forum/view.php,v retrieving revision 1.1.1.1 diff -u -r1.1.1.1 view.php --- moodle/mod/forum/view.php 20 Jan 2009 08:05:58 -0000 1.1.1.1 +++ moodle/mod/forum/view.php 18 Feb 2009 18:08:20 -0000 @@ -1,4 +1,5 @@ -wwwroot . '/mod/forum/yesno_ajax.js'); + if ($id) { if (! $cm = get_coursemodule_from_id('forum', $id)) { error("Course Module ID was incorrect"); @@ -90,8 +95,6 @@ add_to_log($course->id, "forum", "view forum", "view.php?f=$forum->id", "$forum->id"); } - - /// Print settings and things across the top // If it's a simple single discussion forum, we need to print the display @@ -122,11 +125,22 @@ if (forum_is_forcesubscribed($forum)) { $streveryoneisnowsubscribed = get_string('everyoneisnowsubscribed', 'forum'); $strallowchoice = get_string('allowchoice', 'forum'); + // Edit for thread subscriptions : addition of $strautothreadsubs + $strautothreadsubs = get_string('autothreadsubs', 'forum'); echo '' . get_string("forcessubscribe", 'forum') . '
'; helpbutton("subscription", $strallowchoice, "forum"); echo ' '; if (has_capability('mod/forum:managesubscriptions', $context)) { echo "id&force=no\">$strallowchoice"; + // Edit for thread subscriptions : Possible to turn on auto-thread subscriptions instead of just allowing forum subs. + if ($forum->forcesubscribe != FORUM_AUTOTHREADSUBSCRIBE) { + switch ($forum->type) { + case "single": + case "eachuser": break; + default: + echo "
id&force=autothread\">$strautothreadsubs"; + } + } } else { echo $streveryoneisnowsubscribed; } @@ -140,14 +154,40 @@ $streveryonecannowchoose = get_string("everyonecannowchoose", "forum"); $strforcesubscribe = get_string("forcesubscribe", "forum"); $strshowsubscribers = get_string("showsubscribers", "forum"); - echo '' . get_string("allowsallsubscribe", 'forum') . '
'; + // Edit for thread subscriptions : addition of $strautothreadsubs, $strautosubscriptions and $strforcesthreadsubs; use of $strthisforumsubs + $strautothreadsubs = get_string('autothreadsubs', 'forum'); + $strautosubscriptions = get_string('autosubscriptions', 'forum'); + $strallowsallsubs = get_string("allowsallsubscribe", 'forum'); + $strforcesthreadsubs = get_string("forcesthreadsubs", 'forum'); + switch($forum->forcesubscribe) { + case FORUM_AUTOTHREADSUBSCRIBE: + $strthisforumsubs = $strautosubscriptions; + break; + case FORUM_FORCETHREADSUBSCRIBE: + $strthisforumsubs = $strforcesthreadsubs; + break; + default: + $strthisforumsubs = $strallowsallsubs; + } + echo '' . $strthisforumsubs . '
'; helpbutton("subscription", $strforcesubscribe, "forum"); echo ' '; if (has_capability('mod/forum:managesubscriptions', $context)) { echo "id&force=yes\">$strforcesubscribe"; + // Edit for thread subscriptions : Possible to turn on auto-thread subscriptions instead of just forcing forum subs. + if ($forum->forcesubscribe != FORUM_AUTOTHREADSUBSCRIBE) { + switch ($forum->type) { + case "single": + case "eachuser": break; + default: + echo "
id&force=autothread\">$strautothreadsubs"; + } + } } else { - echo ''.$streveryonecannowchoose.''; + if ($forum->forcesubscribe != FORUM_FORCETHREADSUBSCRIBE) { + echo ''.$streveryonecannowchoose.''; + } } if(has_capability('mod/forum:viewsubscribers', $context)){ @@ -186,13 +226,34 @@ // print_box_end(); // subscription } + +// Added for thread-based subscriptions: +// If forcesubscribe is set to options 4 to 6 and user has some thread subscriptions +// show checkbox for 'subscribedthreadfirst' xxxx +// Button would mean nothing in the Single discussion case, but is likely irrelevant +// in 'eachuser' and 'teacher' case. Currently $order not passed through to these anyway. + switch ($forum->type ) { + case 'single': + case 'eachuser': + case 'teacher': + break; + default: + if (forum_is_subscription_to_threads_allowed($USER->id, $forum)) { + if (forum_is_subscribed_to_thread($USER->id, $forum)) { + echo ''; + } + } + } + // print_box_end(); // subscription echo ''; // print_box_end(); // forumcontrol // print_box(' ', 'clearer'); - + if (!empty($forum->blockafter) && !empty($forum->blockperiod)) { $a->blockafter = $forum->blockafter; @@ -267,12 +328,11 @@ } echo '
'; if (!empty($showall)) { - forum_print_latest_discussions($course, $forum, 0, 'header', '', -1, -1, -1, 0, $cm); + forum_print_latest_discussions($course, $forum, 0, 'header', '', -1, -1, -1, 0, $cm, $order); } else { - forum_print_latest_discussions($course, $forum, -1, 'header', '', -1, -1, $page, $CFG->forum_manydiscussions, $cm); + forum_print_latest_discussions($course, $forum, -1, 'header', '', -1, -1, $page, $CFG->forum_manydiscussions, $cm, $order); } - break; } print_footer($course); Index: moodle/mod/forum/yesno.php =================================================================== RCS file: moodle/mod/forum/yesno.php diff -N moodle/mod/forum/yesno.php --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ moodle/mod/forum/yesno.php 20 Feb 2009 11:09:17 -0000 @@ -0,0 +1,81 @@ +$d) { + if (substr($k,0,6) == 'submit') { + $thread = substr($k,7,strlen($k)-7); + } + } + // ...then the forumid appears only once at the start of 'ajaxform' + $forumid = $data['forumid']; + // ...whilst the 'subscribe' state must be retreive from the button's own subscribe_# + $subscribe= $data['subscribe_'.$thread]; + + if (!$forum = get_record('forum', 'id', $forumid)) { + error("Forum ID was incorrect"); + } + + if (!$course = get_record('course', 'id', $forum->course)) { + error("Course ID was incorrect"); + } + + if (!$cm = get_coursemodule_from_instance('forum', $forum->id)) { + error("Course Module ID was incorrect"); + } else { + $forum->cmidnumber = $cm->id; //MDL-12961 + } + + require_login($course, false, $cm); + + $context = get_context_instance(CONTEXT_MODULE, $cm->id); + + $returnto = "view.php?f=".$forum->id; + + $redirectwording = get_string("disallowsubscribe", "forum"); + + if ($thread && (has_capability('mod/forum:initialsubscriptions', $context) || + has_capability('mod/forum:managesubscriptions', $context))) { + // Use a 'soft' permission here to make sure the button/link works if it exists in the first + // place, but should this use 'mod/forum:viewdiscussion'? + // Should this just be if ($thread) ? + $alert = 0; + switch($subscribe) { + case 0: + if (has_capability('mod/forum:rate', $context)) { + $alert = forum_alert_unsubscribing_user($USER->id, $forum->id, $thread); + // $alert==1 if thread originator is unsubscribing without rating when this is expected + } + forum_unsubscribe_thread($USER->id, $forum->id, $thread); + if (!empty($alert)) { + // change $returnto to go to discussion and add alert message + $returnto = "discuss.php?d=".$thread."&alert=1"; + } + $redirectwording = get_string("subscribedthreadno", "forum"); + break; + case 1: + forum_subscribe_thread($USER->id, $forum->id, $thread); + $redirectwording = get_string("subscribedthread", "forum"); + } + } + + // Can't test this redirection for ajax enabled, as may be disabled by browser anyway! + redirect($returnto, $redirectwording, 5); + + } else { + error("This page was not accessed correctly"); + } + +?> \ No newline at end of file Index: moodle/mod/forum/yesno_ajax.js =================================================================== RCS file: moodle/mod/forum/yesno_ajax.js diff -N moodle/mod/forum/yesno_ajax.js --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ moodle/mod/forum/yesno_ajax.js 20 Feb 2009 10:43:16 -0000 @@ -0,0 +1,179 @@ +// $Id: yesno_ajax.js based on rate_ajax.js v 1.1.2.3 2009/01/23 16:30:13 stronk7 Exp $ + +/////////////////////////////////////////////////////////////////////////// +// // +// NOTICE OF COPYRIGHT // +// // +// Moodle - Modular Object-Oriented Dynamic Learning Environment // +// http://moodle.org // +// // +// Copyright (C) 1999 onwards Martin Dougiamas http://dougiamas.com // +// (C) 2001-3001 Eloy Lafuente (stronk7) http://contiento.com // +// // +// This program is free software; you can redistribute it and/or modify // +// it under the terms of the GNU General Public License as published by // +// the Free Software Foundation; either version 2 of the License, or // +// (at your option) any later version. // +// // +// This program is distributed in the hope that it will be useful, // +// but WITHOUT ANY WARRANTY; without even the implied warranty of // +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // +// GNU General Public License for more details: // +// // +// http://www.gnu.org/copyleft/gpl.html // +// // +/////////////////////////////////////////////////////////////////////////// + +/// Javascript used to handle AJAX forum ratings + +/** + * This function initializes all the stuff needed to have forum ratings + * working under AJAX. Basically it adds one onload listener that triggers + * the add_menu_listeners() function to add menu listeners + */ +function init_yesno_ajax () { + YAHOO.util.Event.onDOMReady(add_menu_listeners); +} + +/** + * This function adds event listeners to any rating + * menu found in he page (class = forumpostratingmenu) + * and prevents manual submission + */ +function add_menu_listeners(e) { + + /** prevent form submission **/ + var form = YAHOO.util.Dom.get('ajaxform'); + YAHOO.util.Event.addListener(form, 'submit', prevent_form_submission); + + /** add listeners to all rating menus */ + var buttons = YAHOO.util.Dom.getElementsByClassName('subscriptionthreadlink', 'div'); + for (var i=0; idirroot . '/mod/forum/lib.php'); + + global $CFG, $USER; + +/// In developer debug mode, when there is a debug=1 in the URL send as plain text +/// for easier debugging. + if (debugging('', DEBUG_DEVELOPER) && optional_param('debug', false, PARAM_BOOL)) { + header('Content-type: text/plain; charset=UTF-8'); + $debugmode = true; + } else { + header('Content-type: application/json'); + $debugmode = false; + } + +/// Check required params + $forumid = required_param('forumid', PARAM_INT); // forum id + $thread = required_param('thread', PARAM_INT); // thread id + $subscribe = optional_param('subscribe', 0, PARAM_INT); // subscribe : yes/no + + //for ($i=0; $i<10000000; $i++) {} + +/// Here we maintain response contents + $response = array('status'=> 'Error', 'message'=>array()); + + if (isset($forumid) && isset($thread)) { + + if (!$forum = get_record('forum', 'id', $forumid)) { + error("Forum ID was incorrect"); + } + + if (!$course = get_record('course', 'id', $forum->course)) { + error("Course ID was incorrect"); + } + + if (!$cm = get_coursemodule_from_instance('forum', $forum->id)) { + error("Course Module ID was incorrect"); + } else { + $forum->cmidnumber = $cm->id; //MDL-12961 + } + require_login($course, false, $cm); + + $context = get_context_instance(CONTEXT_MODULE, $cm->id); + + $returnto = "view.php?f=".$forum->id; + + $redirectwording = get_string("disallowsubscribe", "forum"); + + if ($thread && (has_capability('mod/forum:initialsubscriptions', $context) || + has_capability('mod/forum:managesubscriptions', $context))) { + // Use a 'soft' permission here to make sure the button/link works if it exists in the first + // place, but should this use 'mod/forum:viewdiscussion'? + $alert = 0; + switch($subscribe) { + case 0: + if (has_capability('mod/forum:rate', $context)) { + $alert = forum_alert_unsubscribing_user($USER->id, $forum->id, $thread); + // $alert==1 if thread originator is unsubscribing without rating when this is expected + } + forum_unsubscribe_thread($USER->id, $forum->id, $thread); + $redirectwording = get_string("subscribedthreadno", "forum"); + $response['message'][0] = 1; + $response['message'][1] = get_string('no'); + $response['message'][2] = get_string('subscribestartthreadclick', 'forum'); + $response['message'][3] = $alert; + break; + case 1: + forum_subscribe_thread($USER->id, $forum->id, $thread); + $redirectwording = get_string("subscribedthread", "forum"); + $response['message'][0] = 0; + $response['message'][1] = get_string('yes'); + $response['message'][2] = get_string('subscribestopthreadclick', 'forum'); + $response['message'][3] = 0; + } + } + + if (!(ajaxenabled() && !empty($CFG->forum_ajaxrating))) { + redirect($returnto, $redirectwording, 1); + } + + } else { + error("This page was not accessed correctly"); + } + + $response['status'] = 'Ok'; + echo json_encode($response); + +?> Index: moodle/theme/standard/styles_layout.css =================================================================== RCS file: /Users/John/Documents/JWC/Moodle 1.9.4 CVS/moodle 1.9.4/moodle/theme/standard/styles_layout.css,v retrieving revision 1.1.1.1 diff -u -r1.1.1.1 styles_layout.css --- moodle/theme/standard/styles_layout.css 28 Jan 2009 08:04:40 -0000 1.1.1.1 +++ moodle/theme/standard/styles_layout.css 19 Feb 2009 16:20:33 -0000 @@ -3484,6 +3484,11 @@ width: 35px; } +.forumheaderlist .subscribed { + text-align:center; + white-space: nowrap; +} + .forumheaderlist .discussion .starter { vertical-align: middle; } @@ -3527,6 +3532,12 @@ white-space: nowrap; } +#mod-forum-view .subscribed { + float: center; + text-align:center; + white-space: nowrap; +} + #mod-forum-view .subscription { float: right; text-align:right; @@ -3551,6 +3562,11 @@ text-align:center; padding:10px; } +#mod-forum-discuss .subscription { +float: right; +text-align:right; +white-space: nowrap; +} #mod-forum-index .unread img, #mod-forum-view .unread img { @@ -3562,6 +3578,11 @@ text-align:center; } +#mod-forum-discuss .alert td { + width: 33%; + text-align:left; +} + #email .unsubscribelink { margin-top:20px; border-width: 0px 1px 0px 0px;
+ +