Index: mod/forum/mod_form.php
===================================================================
--- mod/forum/mod_form.php	(revision 25)
+++ mod/forum/mod_form.php	(revision 29)
@@ -28,6 +28,12 @@
         $mform->setHelpButton('intro', array('writing', 'questions', 'richtext'), false, 'editorhelpbutton');
 
         $options = array();
+        $options[0] = get_string('anonno', 'forum');
+        $options[1] = get_string('anonyes', 'forum');
+        $options[2] = get_string('anonoptional', 'forum');
+        $mform->addElement('select', 'anonymous', get_string('allowanonymous', 'forum'), $options);
+
+        $options = array();
         $options[0] = get_string('no');
         $options[1] = get_string('yesforever', 'forum');
         $options[FORUM_INITIALSUBSCRIBE] = get_string('yesinitially', 'forum');
Index: mod/forum/lib.php
===================================================================
--- mod/forum/lib.php	(revision 25)
+++ mod/forum/lib.php	(revision 29)
@@ -417,6 +417,9 @@
                 $posttext = forum_make_mail_text($course, $forum, $discussion, $post, $userfrom, $userto);
                 $posthtml = forum_make_mail_html($course, $forum, $discussion, $post, $userfrom, $userto);
 
+                $post->anonymous = $forum->anonymous == 1 ? true : ($forum->anonymous == 2 ? $post->anonymous : false);
+                $userfrom = $post->anonymous ? $CFG->anonymous_name : $userfrom;
+
                 // Send the post now!
 
                 mtrace('Sending ', '');
@@ -775,6 +778,8 @@
 function forum_make_mail_text($course, $forum, $discussion, $post, $userfrom, $userto, $bare = false) {
     global $CFG, $USER;
 
+    $post->anonymous = $forum->anonymous == 1 ? true : ($forum->anonymous == 2 ? $post->anonymous : false);
+
     if (!isset($userto->viewfullnames[$forum->id])) {
         if (!$cm = get_coursemodule_from_instance('forum', $forum->id, $course->id)) {
             error('Course Module ID was incorrect');
@@ -792,7 +797,7 @@
     }
 
     $by = New stdClass;
-    $by->name = fullname($userfrom, $viewfullnames);
+    $by->name = $post->anonymous ? $CFG->anonymous_name : fullname($userfrom, $viewfullnames);
     $by->date = userdate($post->modified, "", $userto->timezone);
 
     $strbynameondate = get_string('bynameondate', 'forum', $by);
@@ -1059,7 +1064,7 @@
                                           JOIN {$CFG->prefix}forum_discussions d ON d.id = p.discussion
                                           JOIN {$CFG->prefix}forum f             ON f.id = d.forum
                                           JOIN {$CFG->prefix}user u              ON u.id = p.userid
-                                    WHERE p.created > $timestart AND f.course = {$course->id}
+                                    WHERE p.created > $timestart AND f.course = {$course->id} AND anonymous = 0
                                  ORDER BY p.id ASC")) { // order by initial posting date
          return false;
     }
@@ -2178,6 +2183,8 @@
 
     global $CFG;
 
+    $post->anonymous = $forum->anonymous == 1 ? true : ($forum->anonymous == 2 ? $post->anonymous : false);
+
     if (!isset($userto->viewfullnames[$forum->id])) {
         if (!$cm = get_coursemodule_from_instance('forum', $forum->id, $course->id)) {
             error('Course Module ID was incorrect');
@@ -2192,11 +2199,12 @@
     $options = new object();
     $options->para = true;
     $formattedtext = format_text(trusttext_strip($post->message), $post->format, $options, $course->id);
+    $anonpicture = '<img alt="' . $CFG->anonymous_name . '" src="' . $CFG->themewww . '/' . current_theme() . '/pix/anonymous.png' . '"/>';
 
     $output = '<table border="0" cellpadding="3" cellspacing="0" class="forumpost">';
 
     $output .= '<tr class="header"><td width="35" valign="top" class="picture left">';
-    $output .= print_user_picture($userfrom, $course->id, $userfrom->picture, false, true);
+    $output .= $post->anonymous ? $anonpicture  : print_user_picture($userfrom, $course->id, $userfrom->picture, false, true);
     $output .= '</td>';
 
     if ($post->parent) {
@@ -2208,7 +2216,7 @@
 
     $fullname = fullname($userfrom, $viewfullnames);
     $by = new object();
-    $by->name = '<a href="'.$CFG->wwwroot.'/user/view.php?id='.$userfrom->id.'&amp;course='.$course->id.'">'.$fullname.'</a>';
+    $by->name = $post->anonymous ? $CFG->anonymous_name : '<a href="'.$CFG->wwwroot.'/user/view.php?id='.$userfrom->id.'&amp;course='.$course->id.'">'.$fullname.'</a>';
     $by->date = userdate($post->modified, '', $userto->timezone);
     $output .= '<div class="author">'.get_string('bynameondate', 'forum', $by).'</div>';
 
@@ -2303,8 +2311,9 @@
     static $strpruneheading, $displaymode;
     static $strmarkread, $strmarkunread, $istracked;
 
-    $post->course = $course->id;
-    $post->forum  = $forum->id;
+    $post->course    = $course->id;
+    $post->forum     = $forum->id;
+    $post->anonymous = $forum->anonymous == 1 ? true : ($forum->anonymous == 2 ? $post->anonymous : false);
 
     // caching
     if (!isset($cm->cache)) {
@@ -2402,9 +2411,10 @@
     $postuser->lastname  = $post->lastname;
     $postuser->imagealt  = $post->imagealt;
     $postuser->picture   = $post->picture;
+    $anonpicture         = '<img alt="' . $CFG->anonymous_name . '" src="' . $CFG->themewww . '/' . current_theme() . '/pix/anonymous.png' . '"/>';
 
     echo '<tr class="header"><td class="picture left">';
-    print_user_picture($postuser, $course->id);
+    $post->anonymous ? print($anonpicture) : print_user_picture($postuser, $course->id);
     echo '</td>';
 
     if ($post->parent) {
@@ -2422,8 +2432,14 @@
     echo '<div class="author">';
     $fullname = fullname($postuser, $cm->cache->caps['moodle/site:viewfullnames']);
     $by = new object();
-    $by->name = '<a href="'.$CFG->wwwroot.'/user/view.php?id='.
-                $post->userid.'&amp;course='.$course->id.'">'.$fullname.'</a>';
+
+    if ($post->anonymous) {
+       $by->name = $CFG->anonymous_name;
+    } else {
+       $by->name = '<a href="'.$CFG->wwwroot.'/user/view.php?id='.
+            $post->userid.'&amp;course='.$course->id.'">'.$fullname.'</a>';
+    }
+
     $by->date = userdate($post->modified);
     print_string('bynameondate', 'forum', $by);
     echo '</div></td></tr>';
@@ -2654,6 +2670,16 @@
     static $rowcount;
     static $strmarkalldread;
 
+    // MDL-1071
+    // Because the discussion list doesn't actually use the post to build the page we have to
+    // load each post to see if it's anonymous, but only if anonymity is optional for this forum.
+    if ($forum->anonymous == 2) {
+        $actual_post = get_record('forum_posts', 'id', $post->id);
+        $post->anonymous = $actual_post->anonymous;
+    } else {
+        $post->anonymous = $forum->anonymous == 1 ? true : ($forum->anonymous == 2 ? $post->anonymous : false);
+    }
+
     if (empty($modcontext)) {
         if (!$cm = get_coursemodule_from_instance('forum', $forum->id, $forum->course)) {
             error('Course Module ID was incorrect');
@@ -2685,15 +2711,22 @@
     $postuser->lastname = $post->lastname;
     $postuser->imagealt = $post->imagealt;
     $postuser->picture = $post->picture;
+    $anonpicture = '<img alt="' . $CFG->anonymous_name . '" src="' . $CFG->themewww . '/' . current_theme() . '/pix/anonymous.png' . '"/>';
 
     echo '<td class="picture">';
-    print_user_picture($postuser, $forum->course);
+    $post->anonymous ? print($anonpicture) : print_user_picture($postuser, $forum->course);
     echo "</td>\n";
 
     // User name
     $fullname = fullname($post, has_capability('moodle/site:viewfullnames', $modcontext));
     echo '<td class="author">';
-    echo '<a href="'.$CFG->wwwroot.'/user/view.php?id='.$post->userid.'&amp;course='.$forum->course.'">'.$fullname.'</a>';
+
+    if ($post->anonymous) {
+        echo $CFG->anonymous_name;
+    } else {
+        echo '<a href="'.$CFG->wwwroot.'/user/view.php?id='.$post->userid.'&amp;course='.$forum->course.'">'.$fullname.'</a>';
+    }
+
     echo "</td>\n";
 
     // Group picture
@@ -2750,8 +2783,10 @@
     $usermodified->id        = $post->usermodified;
     $usermodified->firstname = $post->umfirstname;
     $usermodified->lastname  = $post->umlastname;
-    echo '<a href="'.$CFG->wwwroot.'/user/view.php?id='.$post->usermodified.'&amp;course='.$forum->course.'">'.
-         fullname($usermodified).'</a><br />';
+    if(!$post->anonymous) {
+        echo '<a href="'.$CFG->wwwroot.'/user/view.php?id='.$post->usermodified.'&amp;course='.$forum->course.'">'.
+             fullname($usermodified).'</a><br />';
+    }
     echo '<a href="'.$CFG->wwwroot.'/mod/forum/discuss.php?d='.$post->discussion.$parenturl.'">'.
           userdate($usedate, $datestring).'</a>';
     echo "</td>\n";
@@ -3375,6 +3410,7 @@
     $post->attachment = "";
     $post->forum      = $forum->id;     // speedup
     $post->course     = $forum->course; // speedup
+    $post->anonymous  = $forum->anonymous == 1 ? 1 : ($forum->anonymous == 2 ? (int)$post->anonymous : 0);
 
     if (! $post->id = insert_record("forum_posts", $post)) {
         return false;
@@ -3461,6 +3497,7 @@
     $post->course      = $forum->course; // speedup
     $post->format      = $discussion->format;
     $post->mailnow     = $discussion->mailnow;
+    $post->anonymous   = $forum->anonymous == 1 ? 1 : ($forum->anonymous == 2 ? $discussion->anonymous : 0);
 
     if (! $post->id = insert_record("forum_posts", $post) ) {
         return 0;
@@ -4494,7 +4531,13 @@
                     continue;
                 }
                 $by = new object();
-                $by->name = fullname($post, $canviewfullnames);
+
+                if($post->anonymous) {
+                    $by->name = $CFG->anonymous_name;
+                } else {
+                    $by->name = fullname($post, $canviewfullnames);
+                }
+
                 $by->date = userdate($post->modified);
 
                 if ($istracking) {
@@ -4595,7 +4638,7 @@
                                           JOIN {$CFG->prefix}forum f             ON f.id = d.forum
                                           JOIN {$CFG->prefix}user u              ON u.id = p.userid
                                           $groupjoin
-                                    WHERE p.created > $timestart AND f.id = $cm->instance
+                                    WHERE p.created > $timestart AND p.anonymous = 0 AND f.id = $cm->instance
                                           $userselect $groupselect
                                  ORDER BY p.id ASC")) { // order by initial posting date
          return;
Index: mod/forum/post_form.php
===================================================================
--- mod/forum/post_form.php	(revision 25)
+++ mod/forum/post_form.php	(revision 29)
@@ -64,6 +64,11 @@
             $mform->addElement('checkbox', 'mailnow', get_string('mailnow', 'forum'));
         }
 
+        // MDL-1071
+        if ($forum->anonymous == 2) {
+            $mform->addElement('checkbox', 'anonymous', get_string('anonymouspost', 'forum'));
+        }
+
         if (!empty($CFG->forum_enabletimedposts) && !$post->parent && has_capability('mod/forum:viewhiddentimedposts', $coursecontext)) {
             $mform->addElement('header', '', get_string('displayperiod', 'forum'));
 
Index: mod/forum/user.php
===================================================================
--- mod/forum/user.php	(revision 25)
+++ mod/forum/user.php	(revision 29)
@@ -60,12 +60,12 @@
     switch ($mode) {
         case 'posts' :
             $searchterms = array('userid:'.$user->id);
-            $extrasql = '';
+            $extrasql = 'AND anonymous = 0';
             break;
 
         default:
             $searchterms = array('userid:'.$user->id);
-            $extrasql = 'AND p.parent = 0';
+            $extrasql = 'AND p.parent = 0 AND anonymous = 0';
             break;
     }
     
@@ -84,11 +84,8 @@
     }
     
     // Get the posts.
-    if ($posts = forum_search_posts($searchterms, $searchcourse, $page*$perpage, $perpage, 
-                                    $totalcount, $extrasql)) {
-        
-        print_paging_bar($totalcount, $page, $perpage, 
-                         "user.php?id=$user->id&amp;course=$course->id&amp;mode=$mode&amp;perpage=$perpage&amp;");
+    if ($posts = forum_search_posts($searchterms, $searchcourse, $page*$perpage, $perpage, $totalcount, $extrasql)) {
+        print_paging_bar($totalcount, $page, $perpage, "user.php?id=$user->id&amp;course=$course->id&amp;mode=$mode&amp;perpage=$perpage&amp;");
 
         $discussions = array();
         $forums      = array();
Index: mod/forum/post.php
===================================================================
--- mod/forum/post.php	(revision 25)
+++ mod/forum/post.php	(revision 29)
@@ -13,8 +13,8 @@
     $prune   = optional_param('prune', 0, PARAM_INT);
     $name    = optional_param('name', '', PARAM_CLEAN);
     $confirm = optional_param('confirm', 0, PARAM_INT);
+    $isanon  = optional_param('anonymous', 0, PARAM_INT) ? true : false;
 
-
     //these page_params will be passed as hidden variables later in the form.
     $page_params = array('reply'=>$reply, 'forum'=>$forum, 'edit'=>$edit);
 
@@ -111,6 +111,7 @@
         $post->subject    = '';
         $post->userid     = $USER->id;
         $post->message    = '';
+        $post->anonymous  = $isanon;
 
         if ($groupmode = groups_get_activity_groupmode($cm)) {
             $post->groupid = groups_get_activity_group($cm);
@@ -175,6 +176,7 @@
         $post->subject     = $parent->subject;
         $post->userid      = $USER->id;
         $post->message     = '';
+        $post->anonymous  = $isanon;
 
         $strre = get_string('re', 'forum');
         if (!(substr($post->subject, 0, strlen($strre)) == $strre)) {
@@ -387,6 +389,7 @@
             $newpost->id      = $post->id;
             $newpost->parent  = 0;
             $newpost->subject = $name;
+            $newpost->anonymous = $isanon;
 
             if (!update_record("forum_posts", $newpost)) {
                 error('Could not update the original post');
@@ -723,12 +726,12 @@
     $subscribe=(isset($post->forum)&&forum_is_subscribed($USER->id, $post->forum)) ||
                     (!empty($USER->autosubscribe));
 
-
     $mform_post->set_data(array(    'general'=>$heading,
                                         'subject'=>$post->subject,
                                         'message'=>$post->message,
                                         'subscribe'=>$subscribe?1:0,
                                         'mailnow'=>!empty($post->mailnow),
+                                        'anonymous'=>($post->anonymous)?1:0,
                                         'userid'=>$post->userid,
                                         'parent'=>$post->parent,
                                         'discussion'=>$post->discussion,
Index: lang/en_utf8/forum.php
===================================================================
--- lang/en_utf8/forum.php	(revision 25)
+++ lang/en_utf8/forum.php	(revision 29)
@@ -13,6 +13,7 @@
 $string['aggregatesum'] = 'Sum of ratings';
 $string['aggregatetype'] = 'Aggregate type';
 $string['allforums'] = 'All forums';
+$string['allowanonymous'] = 'Anonymize posts?';
 $string['allowchoice'] = 'Allow everyone to choose';
 $string['allowdiscussions'] = 'Can a $a post to this forum?';
 $string['allowratings'] = 'Allow posts to be rated?';
@@ -20,6 +21,10 @@
 $string['allowsdiscussions'] = 'This forum allows each person to start one discussion topic.';
 $string['allsubscribe'] = 'Subscribe to all forums';
 $string['allunsubscribe'] = 'Unsubscribe from all forums';
+$string['anonno'] = 'No, never';
+$string['anonoptional'] = 'Optional (let the user decide)';
+$string['anonyes'] = 'Yes, all posts';
+$string['anonymouspost'] = 'Post anonymously';
 $string['anyfile'] = 'Any file';
 $string['attachment'] = 'Attachment';
 $string['blockafter'] = 'Post threshold for blocking';
