# This patch file was generated by NetBeans IDE
# This patch can be applied using context Tools: Apply Diff Patch action on respective folder.
# It uses platform neutral UTF-8 encoding.
# Above lines and this line are ignored by the patching process.
Index: moodle/course/moodleform_mod.php
--- moodle/course/moodleform_mod.php Base (1.57)
+++ moodle/course/moodleform_mod.php Locally Modified (Based On 1.57)
@@ -343,13 +343,16 @@
         }
 
         if (plugin_supports('mod', $this->_modname, FEATURE_RATE, false)) {
-            $mform->addElement('header', 'modstandardratings', get_string('ratings', 'ratings'));
+            require_once('../rating/lib.php');
+            $rm = new rating_manager();
 
+            $mform->addElement('header', 'modstandardratings', get_string('ratings', 'rating'));
+
             //$mform->addElement('checkbox', 'assessed', get_string('allowratings', 'ratings') , get_string('ratingsuse', 'ratings'));
 
-            $mform->addElement('select', 'assessed', get_string('aggregatetype', 'ratings') , forum_get_aggregate_types());
+            $mform->addElement('select', 'assessed', get_string('aggregatetype', 'rating') , $rm->get_aggregate_types());
             $mform->setDefault('assessed', 0);
-            $mform->setHelpButton('assessed', array('assessaggregate', get_string('aggregatetype', 'ratings'), 'forum'));
+            $mform->setHelpButton('assessed', array('assessaggregate', get_string('aggregatetype', 'rating'), 'forum'));
 
             $mform->addElement('modgrade', 'scale', get_string('grade'), false);
             $mform->disabledIf('scale', 'assessed', 'eq', 0);
Index: moodle/lib/db/upgradelib.php
--- moodle/lib/db/upgradelib.php Base (1.35)
+++ moodle/lib/db/upgradelib.php Locally Modified (Based On 1.35)
Index: moodle/lib/outputrenderers.php
--- moodle/lib/outputrenderers.php Base (1.181)
+++ moodle/lib/outputrenderers.php Locally Modified (Based On 1.181)
@@ -1241,6 +1241,10 @@
         global $CFG, $USER;
         static $havesetupjavascript = false;
 
+        if( $rating->settings->aggregationmethod == RATING_AGGREGATE_NONE ){
+            return null;//ratings are turned off
+        }
+
         $useajax = !empty($CFG->enableajax);
 
         //include required Javascript
@@ -1249,71 +1253,99 @@
             $havesetupjavascript = true;
         }
 
+        //check the item we're rating was created in the assessable time window
+        $inassessablewindow = true;
+        if ($rating->settings->assesstimestart && $rating->settings->assesstimefinish) {
+            if ($rating->itemtimecreated < $rating->settings->assesstimestart || $item->itemtimecreated > $rating->settings->assesstimefinish) {
+                $inassessablewindow = false;
+            }
+        }
+
         $strrate = get_string("rate", "rating");
-        $strratings = ''; //the string we'll return
+        $ratinghtml = ''; //the string we'll return
 
+        //if the item doesnt belong to the current user
+        if($rating->itemuserid!=$USER->id) {
         if($rating->settings->permissions->canview || $rating->settings->permissions->canviewall) {
+                $aggregatelabel = '';
             switch ($rating->settings->aggregationmethod) {
                 case RATING_AGGREGATE_AVERAGE :
-                    $strratings .= get_string("aggregateavg", "forum");
+                        $aggregatelabel .= get_string("aggregateavg", "forum");
                     break;
                 case RATING_AGGREGATE_COUNT :
-                    $strratings .= get_string("aggregatecount", "forum");
+                        $aggregatelabel .= get_string("aggregatecount", "forum");
                     break;
                 case RATING_AGGREGATE_MAXIMUM :
-                    $strratings .= get_string("aggregatemax", "forum");
+                        $aggregatelabel .= get_string("aggregatemax", "forum");
                     break;
                 case RATING_AGGREGATE_MINIMUM :
-                    $strratings .= get_string("aggregatemin", "forum");
+                        $aggregatelabel .= get_string("aggregatemin", "forum");
                     break;
                 case RATING_AGGREGATE_SUM :
-                    $strratings .= get_string("aggregatesum", "forum");
+                        $aggregatelabel .= get_string("aggregatesum", "forum");
                     break;
             }
 
-            if (empty($strratings)) {
-                $strratings .= $strrate;
-            }
-            $strratings .= ': ';
+                //$scalemax = 0;//no longer displaying scale max
+                $aggregatestr = '';
 
-            $scalemax = 0;
-            $ratingstr = null;
-
+                if($rating->rating) { //this will prevent the user seeing the aggregate until they have submitted a rating
             if ( is_array($rating->settings->scale->scaleitems) ) {
-                $scalemax = $rating->settings->scale->scaleitems[ count($rating->settings->scale->scaleitems)-1 ];
-                $ratingstr = $rating->settings->scale->scaleitems[$rating->rating];
+                        //$scalemax = $rating->settings->scale->scaleitems[ count($rating->settings->scale->scaleitems) ];
+                        $aggregatestr .= $rating->settings->scale->scaleitems[round($rating->aggregate)];//round aggregate as we're using it as an index
             }
             else { //its numeric
-                $scalemax = $rating->settings->scale->scaleitems;
-                $ratingstr = round($rating->aggregate,1);
+                        //$scalemax = $rating->settings->scale->scaleitems;
+                        $aggregatestr .= round($rating->aggregate,1);
             }
+                }
 
-            $aggstr = "{$ratingstr} / $scalemax ({$rating->count}) ";
+                $countstr = null;
+                if($rating->count>0) {
+                    $countstr = "<span id='ratingcount{$rating->itemid}'>({$rating->count})</span>";
+                } else {
+                    $countstr = "<span id='ratingcount{$rating->itemid}'></span>";
+                }
 
+                //$aggregatehtml = "{$ratingstr} / $scalemax ({$rating->count}) ";
+                $aggregatehtml = "$aggregatelabel: <span id='ratingaggregate{$rating->itemid}'>{$aggregatestr}</span> $countstr ";
+
             if ($rating->settings->permissions->canviewall) {
-                $link = new moodle_url("/rating/index.php?contextid={$rating->context->id}&itemid={$rating->itemid}&scaleid={$rating->scaleid}");
-                $action = new popup_action('click', $link, 'ratings', array('height' => 400, 'width' => 600));
-                $strratings .= $this->action_link($link, $aggstr, $action);
+                    $url = "/rating/index.php?contextid={$rating->context->id}&itemid={$rating->itemid}&scaleid={$rating->settings->scale->id}";
+                    $nonpopuplink = new moodle_url($url);
+                    $popuplink = new moodle_url("$url&popup=1");
+
+                    $action = new popup_action('click', $popuplink, 'ratings', array('height' => 400, 'width' => 600));
+                    $ratinghtml .= $this->action_link($nonpopuplink, $aggregatehtml, $action);
             } else if ($rating->settings->permissions->canview) {
-                $strratings .= $aggstr;
+                    $ratinghtml .= $aggregatehtml;
             }
         }
 
         //todo andrew alter the below if to deny guest users the ability to post ratings.
         //Petr to define "guest"
+
         $formstart = null;
-        if($rating->settings->permissions->canrate) {
-            //dont use $rating->userid below as it will be null if the user hasnt already rated the item
+            //if the item doesnt belong to the current user, the user has permission to rate
+            //and we're not outside of a defined assessable period
+            //if( $rating->itemuserid!=$USER->id && $rating->settings->permissions->canrate && $inassessablewindow) {
+            if( $rating->itemuserid!=$USER->id && $rating->settings->permissions->canrate && $inassessablewindow) {
             $formstart = <<<END
-<form id="postrating{$rating->itemid}" class="postratingform" method="post" action="rating/rate.php">
+<form id="postrating{$rating->itemid}" class="postratingform" method="post" action="{$CFG->wwwroot}/rating/rate.php">
 <div class="ratingform">
 <input type="hidden" class="ratinginput" name="contextid" value="{$rating->context->id}" />
 <input type="hidden" class="ratinginput" name="itemid" value="{$rating->itemid}" />
 <input type="hidden" class="ratinginput" name="scaleid" value="{$rating->settings->scale->id}" />
 <input type="hidden" class="ratinginput" name="returnurl" value="{$rating->settings->returnurl}" />
+<input type="hidden" class="ratinginput" name="rateduserid" value="{$rating->itemuserid}" />
+<input type="hidden" class="ratinginput" name="aggregation" value="{$rating->settings->aggregationmethod}" />
 END;
-            $strratings = $formstart.$strratings;
+                if (empty($ratinghtml)) {
+                    $ratinghtml .= $strrate.': ';
+                }
 
+                $ratinghtml = $formstart.$ratinghtml;
+
             //generate an array of values for numeric scales
             $scalearray = $rating->settings->scale->scaleitems;
             if( !is_array($scalearray) ) { //almost certainly a numerical scale
@@ -1327,20 +1359,19 @@
             }
 
             $scalearray = array(RATING_UNSET_RATING => $strrate.'...') + $scalearray;
-            $strratings .= html_writer::select($scalearray, 'rating', $rating->rating, false, array('class'=>'postratingmenu ratinginput','id'=>'menurating'.$rating->itemid));
+                $ratinghtml .= html_writer::select($scalearray, 'rating', $rating->rating, false, array('class'=>'postratingmenu ratinginput','id'=>'menurating'.$rating->itemid));
 
             //output submit button
-            $strratings .= '<span class="ratingsubmit"><input type="submit" class="postratingmenusubmit" id="postratingsubmit'.$rating->itemid.'" value="'.s(get_string('rate', 'rating')).'" />';
+                $ratinghtml .= '<span class="ratingsubmit"><input type="submit" class="postratingmenusubmit" id="postratingsubmit'.$rating->itemid.'" value="'.s(get_string('rate', 'rating')).'" />';
 
-            if ( is_array($rating->settings->scale) ) {
-                //todo andrew where can we get the course id from?
-                //$strratings .= $this->help_icon_scale($course->id, $scale);
-                $strratings .= $this->help_icon_scale(1, $rating->settings->scale);
+                if ( is_array($rating->settings->scale->scaleitems) ) {
+                    $ratinghtml .= $this->help_icon_scale($rating->settings->scale->courseid, $rating->settings->scale);
             }
-            $strratings .= '</span></div></form>';
+                $ratinghtml .= '</span></div></form>';
         }
+        }
 
-        return $strratings;
+        return $ratinghtml;
     }
 
     /*
Index: moodle/mod/forum/db/install.xml
--- moodle/mod/forum/db/install.xml Base (1.14)
+++ moodle/mod/forum/db/install.xml Locally Modified (Based On 1.14)
@@ -1,5 +1,5 @@
 <?xml version="1.0" encoding="UTF-8" ?>
-<XMLDB PATH="mod/forum/db" VERSION="20090420" COMMENT="XMLDB file for Moodle mod/forum"
+<XMLDB PATH="mod/forum/db" VERSION="20100322" COMMENT="XMLDB file for Moodle mod/forum"
     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
     xsi:noNamespaceSchemaLocation="../../../lib/xmldb/xmldb.xsd"
 >
@@ -88,7 +88,7 @@
         <INDEX NAME="mailed" UNIQUE="false" FIELDS="mailed" PREVIOUS="created"/>
       </INDEXES>
     </TABLE>
-    <TABLE NAME="forum_queue" COMMENT="For keeping track of posts that will be mailed in digest form" PREVIOUS="forum_posts" NEXT="forum_ratings">
+    <TABLE NAME="forum_queue" COMMENT="For keeping track of posts that will be mailed in digest form" PREVIOUS="forum_posts" NEXT="forum_subscriptions">
       <FIELDS>
         <FIELD NAME="id" TYPE="int" LENGTH="10" NOTNULL="true" UNSIGNED="true" SEQUENCE="true" NEXT="userid"/>
         <FIELD NAME="userid" TYPE="int" LENGTH="10" NOTNULL="true" UNSIGNED="true" DEFAULT="0" SEQUENCE="false" PREVIOUS="id" NEXT="discussionid"/>
@@ -105,25 +105,9 @@
         <INDEX NAME="user" UNIQUE="false" FIELDS="userid"/>
       </INDEXES>
     </TABLE>
-    <TABLE NAME="forum_ratings" COMMENT="forum_ratings table retrofitted from MySQL" PREVIOUS="forum_queue" NEXT="forum_subscriptions">
+    <TABLE NAME="forum_subscriptions" COMMENT="Keeps track of who is subscribed to what forum" PREVIOUS="forum_queue" NEXT="forum_read">
       <FIELDS>
         <FIELD NAME="id" TYPE="int" LENGTH="10" NOTNULL="true" UNSIGNED="true" SEQUENCE="true" NEXT="userid"/>
-        <FIELD NAME="userid" TYPE="int" LENGTH="10" NOTNULL="true" UNSIGNED="true" DEFAULT="0" SEQUENCE="false" PREVIOUS="id" NEXT="post"/>
-        <FIELD NAME="post" TYPE="int" LENGTH="10" NOTNULL="true" UNSIGNED="true" DEFAULT="0" SEQUENCE="false" PREVIOUS="userid" NEXT="time"/>
-        <FIELD NAME="time" TYPE="int" LENGTH="10" NOTNULL="true" UNSIGNED="true" DEFAULT="0" SEQUENCE="false" PREVIOUS="post" NEXT="rating"/>
-        <FIELD NAME="rating" TYPE="int" LENGTH="4" NOTNULL="true" UNSIGNED="false" DEFAULT="0" SEQUENCE="false" PREVIOUS="time"/>
-      </FIELDS>
-      <KEYS>
-        <KEY NAME="primary" TYPE="primary" FIELDS="id" NEXT="post"/>
-        <KEY NAME="post" TYPE="foreign" FIELDS="post" REFTABLE="forum_posts" REFFIELDS="id" PREVIOUS="primary"/>
-      </KEYS>
-      <INDEXES>
-        <INDEX NAME="userid" UNIQUE="false" FIELDS="userid"/>
-      </INDEXES>
-    </TABLE>
-    <TABLE NAME="forum_subscriptions" COMMENT="Keeps track of who is subscribed to what forum" PREVIOUS="forum_ratings" NEXT="forum_read">
-      <FIELDS>
-        <FIELD NAME="id" TYPE="int" LENGTH="10" NOTNULL="true" UNSIGNED="true" SEQUENCE="true" NEXT="userid"/>
         <FIELD NAME="userid" TYPE="int" LENGTH="10" NOTNULL="true" UNSIGNED="true" DEFAULT="0" SEQUENCE="false" PREVIOUS="id" NEXT="forum"/>
         <FIELD NAME="forum" TYPE="int" LENGTH="10" NOTNULL="true" UNSIGNED="true" DEFAULT="0" SEQUENCE="false" PREVIOUS="userid"/>
       </FIELDS>
Index: moodle/mod/forum/lib.php
--- moodle/mod/forum/lib.php Base (1.859)
+++ moodle/mod/forum/lib.php Locally Modified (Based On 1.859)
@@ -42,17 +42,6 @@
 define('FORUM_TRACKING_OPTIONAL', 1);
 define('FORUM_TRACKING_ON', 2);
 
-//todo andrew remove this
-define('FORUM_UNSET_POST_RATING', -999);
-
-//todo andrew and remove these
-define ('FORUM_AGGREGATE_NONE', 0); //no ratings
-define ('FORUM_AGGREGATE_AVG', 1);
-define ('FORUM_AGGREGATE_COUNT', 2);
-define ('FORUM_AGGREGATE_MAX', 3);
-define ('FORUM_AGGREGATE_MIN', 4);
-define ('FORUM_AGGREGATE_SUM', 5);
-
 /// STANDARD FUNCTIONS ///////////////////////////////////////////////////////////
 
 /**
@@ -1156,42 +1145,14 @@
         }
         $discussions = forum_get_user_involved_discussions($forum->id, $user->id);
 
-        // preload all user ratings for these discussions - one query only and minimal memory
-        $cm->cache->ratings = array();
-        $cm->cache->myratings = array();
-        if ($postratings = forum_get_all_user_ratings($user->id, $discussions)) {
-            foreach ($postratings as $pr) {
-                if (!isset($cm->cache->ratings[$pr->postid])) {
-                    $cm->cache->ratings[$pr->postid] = array();
-                }
-                $cm->cache->ratings[$pr->postid][$pr->id] = $pr->rating;
-
-                if ($pr->userid == $USER->id) {
-                    $cm->cache->myratings[$pr->postid] = $pr->rating;
-                }
-            }
-            unset($postratings);
-        }
-
         foreach ($posts as $post) {
             if (!isset($discussions[$post->discussion])) {
                 continue;
             }
             $discussion = $discussions[$post->discussion];
 
-            $ratings = null;
-
-            if ($forum->assessed) {
-                if ($scale = make_grades_menu($forum->scale)) {
-                    $ratings =new object();
-                    $ratings->scale = $scale;
-                    $ratings->assesstimestart = $forum->assesstimestart;
-                    $ratings->assesstimefinish = $forum->assesstimefinish;
-                    $ratings->allow = false;
+            forum_print_post($post, $discussion, $forum, $cm, $course, false, false, false);
                 }
-            }
-            forum_print_post($post, $discussion, $forum, $cm, $course, false, false, false, $ratings);
-        }
     } else {
         echo "<p>".get_string("noposts", "forum")."</p>";
     }
@@ -1456,92 +1417,26 @@
  * @param int $userid optional user id, 0 means all users
  * @return array array of grades, false if none
  */
- //todo andrew pretty sure I can remove this
 function forum_get_user_grades($forum, $userid=0) {
-    global $CFG, $DB;
+    global $CFG;
 
-    $params= array();
-    if ($userid) {
-        $params[] = $userid;
-        $user = "AND u.id = ?";
-    } else {
-        $user = "";
-    }
+    require_once($CFG->dirroot.'/rating/lib.php');
+    $rm = new rating_manager();
 
-    $params[] = $forum->id;
+    $ratingoptions = new stdclass();
 
-    $aggtype = $forum->assessed;
-    switch ($aggtype) {
-        case FORUM_AGGREGATE_COUNT :
-            $sql = "SELECT u.id, u.id AS userid, COUNT(fr.rating) AS rawgrade
-                      FROM {user} u, {forum_posts} fp,
-                           {forum_ratings} fr, {forum_discussions} fd
-                     WHERE u.id = fp.userid AND fp.discussion = fd.id AND fr.post = fp.id
-                           AND fr.userid != u.id AND fd.forum = ?
-                           $user
-                  GROUP BY u.id";
-            break;
-        case FORUM_AGGREGATE_MAX :
-            $sql = "SELECT u.id, u.id AS userid, MAX(fr.rating) AS rawgrade
-                      FROM {user} u, {forum_posts} fp,
-                           {forum_ratings} fr, {forum_discussions} fd
-                     WHERE u.id = fp.userid AND fp.discussion = fd.id AND fr.post = fp.id
-                           AND fr.userid != u.id AND fd.forum = ?
-                           $user
-                  GROUP BY u.id";
-            break;
-        case FORUM_AGGREGATE_MIN :
-            $sql = "SELECT u.id, u.id AS userid, MIN(fr.rating) AS rawgrade
-                      FROM {user} u, {forum_posts} fp,
-                           {forum_ratings} fr, {forum_discussions} fd
-                     WHERE u.id = fp.userid AND fp.discussion = fd.id AND fr.post = fp.id
-                           AND fr.userid != u.id AND fd.forum = ?
-                           $user
-                  GROUP BY u.id";
-            break;
-        case FORUM_AGGREGATE_SUM :
-            $sql = "SELECT u.id, u.id AS userid, SUM(fr.rating) AS rawgrade
-                     FROM {user} u, {forum_posts} fp,
-                          {forum_ratings} fr, {forum_discussions} fd
-                    WHERE u.id = fp.userid AND fp.discussion = fd.id AND fr.post = fp.id
-                          AND fr.userid != u.id AND fd.forum = ?
-                          $user
-                 GROUP BY u.id";
-            break;
-        default : //avg
-            $sql = "SELECT u.id, u.id AS userid, AVG(fr.rating) AS rawgrade
-                      FROM {user} u, {forum_posts} fp,
-                           {forum_ratings} fr, {forum_discussions} fd
-                     WHERE u.id = fp.userid AND fp.discussion = fd.id AND fr.post = fp.id
-                           AND fr.userid != u.id AND fd.forum = ?
-                           $user
-                  GROUP BY u.id";
-            break;
-    }
+    //need these to work backwards to get a context id. Is there a better way to get contextid from a module instance?
+    $ratingoptions->modulename = 'forum';
+    $ratingoptions->moduleid   = $forum->id;
+    //$ratingoptions->cmidnumber = $forum->cmidnumber;
 
-    if ($results = $DB->get_records_sql($sql, $params)) {
-        // it could throw off the grading if count and sum returned a rawgrade higher than scale
-        // so to prevent it we review the results and ensure that rawgrade does not exceed the scale, if it does we set rawgrade = scale (i.e. full credit)
-        foreach ($results as $rid=>$result) {
-            if ($forum->scale >= 0) {
-                //numeric
-                if ($result->rawgrade > $forum->scale) {
-                    $results[$rid]->rawgrade = $forum->scale;
-                }
-            } else {
-                //scales
-                if ($scale = $DB->get_record('scale', array('id' => -$forum->scale))) {
-                    $scale = explode(',', $scale->scale);
-                    $max = count($scale);
-                    if ($result->rawgrade > $max) {
-                        $results[$rid]->rawgrade = $max;
-                    }
-                }
-            }
-        }
-    }
+    $ratingoptions->userid = $userid;
+    $ratingoptions->aggregationmethod = $forum->assessed;
+    $ratingoptions->scaleid = $forum->scale;
+    $ratingoptions->itemtable = 'forum_posts';
+    $ratingoptions->itemtableusercolumn = 'userid';
 
-    return $results;
+    return $rm->get_user_grades($ratingoptions);
 }
 
 /**
@@ -2142,46 +2037,6 @@
 }
 
 /**
- * Returns a list of ratings for one specific user for all posts in discussion
- * @global object
- * @global object
- * @param object $discussions the discussions for which we return all ratings
- * @param int $userid the user for who we return all ratings
- * @return array
- */
-function forum_get_all_user_ratings($userid, $discussions) {
-    global $CFG, $DB;
-
-
-    foreach ($discussions as $discussion) {
-     if (!isset($discussionsid)){
-         $discussionsid = $discussion->id;
-     }
-     else {
-         $discussionsid .= ",".$discussion->id;
-     }
-    }
-
-    $sql = "SELECT r.id, r.userid, p.id AS postid, r.rating
-                              FROM {forum_ratings} r,
-                                   {forum_posts} p
-                             WHERE r.post = p.id AND p.userid = :userid";
-
-
-    $params = array();
-    $params['userid'] = $userid;
-    //postgres compability
-    if (!isset($discussionsid)) {
-       $sql .=" AND p.discussion IN (".$discussionsid.")";
-    }
-    $sql .=" ORDER BY p.id ASC";
-
-    return $DB->get_records_sql($sql, $params);
-
-
-}
-
-/**
  * Returns a list of ratings for a particular post - sorted.
  *
  * @global object
@@ -2190,14 +2045,15 @@
  * @param string $sort
  * @return array Array of ratings or false
  */
-function forum_get_ratings($postid, $sort="u.firstname ASC") {
-    global $CFG, $DB;
-    return $DB->get_records_sql("SELECT u.*, r.rating, r.time
-                              FROM {forum_ratings} r,
-                                   {user} u
-                             WHERE r.post = ?
-                               AND r.userid = u.id
-                             ORDER BY $sort", array($postid));
+function forum_get_ratings($context, $postid, $sort="u.firstname ASC") {
+    global $PAGE;
+
+    $options = new stdclass();
+    $options->context = $PAGE->context;
+    $options->itemid = $postid;
+    $options->sort = "ORDER BY $sort";
+
+    get_all_ratings_for_item($options);
 }
 
 /**
@@ -3236,7 +3092,6 @@
  * @param boolean $ownpost Whether this post belongs to the current user.
  * @param boolean $reply Whether to print a 'reply' link at the bottom of the message.
  * @param boolean $link Just print a shortened version of the post as a link to the full post.
- * @param object $ratings -- I don't really know --
  * @param string $footer Extra stuff to print after the message.
  * @param string $highlight Space-separated list of terms to highlight.
  * @param int $post_read true, false or -99. If we already know whether this user
@@ -3247,9 +3102,10 @@
  *          (the default) then print a dummy 'you can't see this post' post.
  *          If false, don't output anything at all.
  * @param bool|null $istracked
+ * @return void
  */
 function forum_print_post($post, $discussion, $forum, &$cm, $course, $ownpost=false, $reply=false, $link=false,
-                          $ratings=NULL, $footer="", $highlight="", $post_read=null, $dummyifcantsee=true, $istracked=null) {
+                          $footer="", $highlight="", $post_read=null, $dummyifcantsee=true, $istracked=null) {
 
     global $USER, $CFG, $OUTPUT;
 
@@ -3523,64 +3379,10 @@
 
 
 // Ratings
-
-    $ratingsmenuused = false;
-    if (!empty($ratings) and isloggedin()) {
-        echo '<div class="ratings">';
-        $useratings = true;
-        if ($ratings->assesstimestart and $ratings->assesstimefinish) {
-            if ($post->created < $ratings->assesstimestart or $post->created > $ratings->assesstimefinish) {
-                $useratings = false;
+    if( !empty($post->rating) ){
+        echo $OUTPUT->render($post->rating);
             }
-        }
-        if ($useratings) {
-            $mypost = ($USER->id == $post->userid);
 
-            $canviewallratings = $cm->cache->caps['mod/forum:viewanyrating'];
-
-            if (isset($cm->cache->ratings)) {
-                if (isset($cm->cache->ratings[$post->id])) {
-                    $allratings = $cm->cache->ratings[$post->id];
-                } else {
-                    $allratings = array(); // no reatings present yet
-                }
-            } else {
-                $allratings = NULL; // not preloaded
-            }
-
-            if (isset($cm->cache->myratings)) {
-                if (isset($cm->cache->myratings[$post->id])) {
-                    $myrating = $cm->cache->myratings[$post->id];
-                } else {
-                    $myrating = FORUM_UNSET_POST_RATING; // no reatings present yet
-                }
-            } else {
-                $myrating = NULL; // not preloaded
-            }
-
-            if ($canviewallratings and !$mypost) {
-                echo '<span class="forumpostratingtext">' .
-                     forum_print_ratings($post->id, $ratings->scale, $forum->assessed, $canviewallratings, $allratings, true) .
-                     '</span>';
-                if (!empty($ratings->allow)) {
-                    echo '&nbsp;';
-                    forum_print_rating_menu($post->id, $USER->id, $ratings->scale, $myrating);
-                    $ratingsmenuused = true;
-                }
-
-            } else if ($mypost) {
-                echo '<span class="forumpostratingtext">' .
-                     forum_print_ratings($post->id, $ratings->scale, $forum->assessed, true, $allratings, true) .
-                     '</span>';
-
-            } else if (!empty($ratings->allow) ) {
-                forum_print_rating_menu($post->id, $USER->id, $ratings->scale, $myrating);
-                $ratingsmenuused = true;
-            }
-        }
-        echo '</div>';
-    }
-
 // Link to post if required
 
     if ($link) {
@@ -3603,8 +3405,6 @@
     if ($istracked && !$CFG->forum_usermarksread && !$post_read) {
         forum_tp_mark_post_read($USER->id, $post, $forum->id);
     }
-
-    return $ratingsmenuused;
 }
 
 
@@ -3795,385 +3595,7 @@
    return substr($message, 0, $truncate);
 }
 
-
 /**
- * Print the multiple ratings on a post given to the current user by others.
- * Forumid prevents the double lookup of the forumid in discussion to determine the aggregate type
- * Scale is an array of ratings
- *
- * @uses FORUM_AGGREGATE_AVG
- * @uses FORUM_AGGREGATE_COUNT
- * @uses FORUM_AGGREGATE_MAX
- * @uses FORUM_AGGREGATE_MIN
- * @uses FORUM_AGGREGATE_SUM
- * @param int $postid
- * @param array $scale
- * @param int $aggregatetype
- * @param bool $link
- * @param array $ratings
- * @param bool $return
- * @return string|void
- */
-function forum_print_ratings($postid, $scale, $aggregatetype, $link=true, $ratings=null, $return=false) {
-    global $OUTPUT;
-    $strratings = '';
-
-    switch ($aggregatetype) {
-        case FORUM_AGGREGATE_AVG :
-            $agg        = forum_get_ratings_mean($postid, $scale, $ratings);
-            $strratings = get_string("aggregateavg", "forum");
-            break;
-        case FORUM_AGGREGATE_COUNT :
-            $agg        = forum_get_ratings_count($postid, $scale, $ratings);
-            $strratings = get_string("aggregatecount", "forum");
-            break;
-        case FORUM_AGGREGATE_MAX :
-            $agg        = forum_get_ratings_max($postid, $scale, $ratings);
-            $strratings = get_string("aggregatemax", "forum");
-            break;
-        case FORUM_AGGREGATE_MIN :
-            $agg        = forum_get_ratings_min($postid, $scale, $ratings);
-            $strratings = get_string("aggregatemin", "forum");
-            break;
-        case FORUM_AGGREGATE_SUM :
-            $agg        = forum_get_ratings_sum($postid, $scale, $ratings);
-            $strratings = get_string("aggregatesum", "forum");
-            break;
-    }
-
-    if ($agg !== "") {
-
-        if (empty($strratings)) {
-            $strratings = get_string("ratings", "forum");
-        }
-
-        $strratings .= ': ';
-
-        if ($link) {
-
-            $link = new moodle_url("/mod/forum/report.php?id=$postid");
-            $action = new popup_action('click', $link, 'ratings', array('height' => 400, 'width' => 600));
-            $strratings .= $OUTPUT->action_link($link, $agg, $action);
-        } else {
-            $strratings .= "$agg ";
-        }
-
-        if ($return) {
-            return $strratings;
-        } else {
-            echo $strratings;
-        }
-    }
-}
-
-
-/**
- * Return the mean rating of a post given to the current user by others.
- *
- * @global object
- * @param int $postid
- * @param array $scal Scale is an array of possible ratings in the scale
- * @param array $ratings Ratings is an optional simple array of actual ratings (just integers)
- * @return string
- */
-function forum_get_ratings_mean($postid, $scale, $ratings=NULL) {
-    global $DB;
-    if (is_null($ratings)) {
-        $ratings = array();
-        if ($rates = $DB->get_records("forum_ratings", array("post" => $postid))) {
-            foreach ($rates as $rate) {
-                $ratings[] = $rate->rating;
-            }
-        }
-    }
-
-    $count = count($ratings);
-
-    if ($count == 0 ) {
-        return "";
-
-    } else if ($count == 1) {
-        $rating = reset($ratings);
-        return $scale[$rating];
-
-    } else {
-        $total = 0;
-        foreach ($ratings as $rating) {
-            $total += $rating;
-        }
-        $mean = round( ((float)$total/(float)$count) + 0.001);  // Little fudge factor so that 0.5 goes UP
-
-        if (isset($scale[$mean])) {
-            return $scale[$mean]." ($count)";
-        } else {
-            return "$mean ($count)";    // Should never happen, hopefully
-        }
-    }
-}
-
-/**
- * Return the count of the ratings of a post given to the current user by others.
- *
- * For numerical grades, the scale index is the same as the real grade value from interval {0..n}
- * and $scale looks like Array( 0 => '0/n', 1 => '1/n', ..., n => 'n/n' )
- *
- * For scales, the index is the order of the scale item {1..n}
- * and $scale looks like Array( 1 => 'poor', 2 => 'weak', 3 => 'good' )
- * In case of no ratings done yet, we have nothing to display.
- *
- * @global object
- * @param int $postid
- * @param array $scale Possible ratings in the scale - the end of the scale is the highest or max grade
- * @param array $ratings An optional simple array of actual ratings (just integers)
- * @return string
- */
-function forum_get_ratings_count($postid, $scale, $ratings=NULL) {
-    global $DB;
-    if (is_null($ratings)) {
-        $ratings = array();
-        if ($rates = $DB->get_records("forum_ratings", array("post" => $postid))) {
-            foreach ($rates as $rate) {
-                $ratings[] = $rate->rating;
-            }
-        }
-    }
-
-    $count = count($ratings);
-    if (! array_key_exists(0, $scale)) {
-        $scaleused = true;
-    } else {
-        $scaleused = false;
-    }
-
-    if ($count == 0) {
-        if ($scaleused) {    // If no rating given yet and we use a scale
-            return get_string('noratinggiven', 'forum');
-        } else {
-            return '';
-        }
-    }
-
-    $maxgradeidx = max(array_keys($scale)); // For numerical grades, the index is the same as the real grade value {0..n}
-                                            // and $scale looks like Array( 0 => '0/n', 1 => '1/n', ..., n => 'n/n' )
-                                            // For scales, the index is the order of the scale item {1..n}
-                                            // and $scale looks like Array( 1 => 'poor', 2 => 'weak', 3 => 'good' )
-
-    if ($count > $maxgradeidx) {      // The count exceeds the max grade
-        $a = new stdClass();
-        $a->count = $count;
-        $a->grade = $scale[$maxgradeidx];
-        return get_string('aggregatecountformat', 'forum', $a);
-    } else {                                // Display the count and the aggregated grade for this post
-        $a = new stdClass();
-        $a->count = $count;
-        $a->grade = $scale[$count];
-        return get_string('aggregatecountformat', 'forum', $a);
-    }
-}
-
-/**
- * Return the max rating of a post given to the current user by others.
- *
- * @global object
- * @param int $postid
- * @param array $scale Scale is an array of possible ratings in the scale
- * @param array $ratings Ratings is an optional simple array of actual ratings (just integers)
- */
-function forum_get_ratings_max($postid, $scale, $ratings=NULL) {
-
-    global $DB;
-    if (is_null($ratings)) {
-        $ratings = array();
-        if ($rates = $DB->get_records("forum_ratings", array("post" => $postid))) {
-            foreach ($rates as $rate) {
-                $ratings[] = $rate->rating;
-            }
-        }
-    }
-
-    $count = count($ratings);
-
-    if ($count == 0 ) {
-        return "";
-
-    } else if ($count == 1) { //this works for max
-        $rating = reset($ratings);
-        return $scale[$rating];
-
-    } else {
-        $max = max($ratings);
-
-        if (isset($scale[$max])) {
-            return $scale[$max]." ($count)";
-        } else {
-            return "$max ($count)";    // Should never happen, hopefully
-        }
-    }
-}
-
-/**
- * Return the min rating of a post given to the current user by others.
- *
- * @global object
- * @param int postid
- * @param array $scale Scale is an array of possible ratings in the scale
- * @param array $ratings  Ratings is an optional simple array of actual ratings (just integers)
- * @return string
- */
-function forum_get_ratings_min($postid, $scale,  $ratings=NULL) {
-    global $DB;
-    if (is_null($ratings)) {
-        $ratings = array();
-        if ($rates = $DB->get_records("forum_ratings", array("post" => $postid))) {
-            foreach ($rates as $rate) {
-                $ratings[] = $rate->rating;
-            }
-        }
-    }
-
-    $count = count($ratings);
-
-    if ($count == 0 ) {
-        return "";
-
-    } else if ($count == 1) {
-        $rating = reset($ratings);
-        return $scale[$rating]; //this works for min
-
-    } else {
-        $min = min($ratings);
-
-        if (isset($scale[$min])) {
-            return $scale[$min]." ($count)";
-        } else {
-            return "$min ($count)";    // Should never happen, hopefully
-        }
-    }
-}
-
-
-/**
- * Return the sum or total of ratings of a post given to the current user by others.
- *
- * @global object
- * @param int $postid
- * @param array $scale Scale is an array of possible ratings in the scale
- * @param array $ratings Ratings is an optional simple array of actual ratings (just integers)
- * @return string
- */
-function forum_get_ratings_sum($postid, $scale, $ratings=NULL) {
-    global $DB;
-    if (is_null($ratings)) {
-        $ratings = array();
-        if ($rates = $DB->get_records("forum_ratings", array("post" => $postid))) {
-            foreach ($rates as $rate) {
-                $ratings[] = $rate->rating;
-            }
-        }
-    }
-
-    $count = count($ratings);
-    $scalecount = count($scale)-1; //this should give us the last element of the scale aka the max grade with  $scale[$scalecount]
-
-    if ($count == 0 ) {
-        return "";
-
-    } else if ($count == 1) { //this works for max.
-        $rating = reset($ratings);
-        return $scale[$rating];
-
-    } else {
-        $total = 0;
-        foreach ($ratings as $rating) {
-            $total += $rating;
-        }
-        if ($total > $scale[$scalecount]) { //if the total exceeds the max grade then set it to the max grade
-            $total = $scale[$scalecount];
-        }
-        if (isset($scale[$total])) {
-            return $scale[$total]." ($count)";
-        } else {
-            return "$total ($count)";    // Should never happen, hopefully
-        }
-    }
-}
-
-/**
- * Return a summary of post ratings given to the current user by others.
- *
- * @global object
- * @param int $postid
- * @param array $scale Scale is an array of possible ratings in the scale
- * @param array $ratings Ratings is an optional simple array of actual ratings (just integers)
- * @return string
- */
-function forum_get_ratings_summary($postid, $scale, $ratings=NULL) {
-    global $DB;
-    if (is_null($ratings)) {
-        $ratings = array();
-        if ($rates = $DB->get_records("forum_ratings", array("post" => $postid))) {
-            foreach ($rates as $rate) {
-                $rating[] = $rate->rating;
-            }
-        }
-    }
-
-
-    if (!$count = count($ratings)) {
-        return "";
-    }
-
-
-    foreach ($scale as $key => $scaleitem) {
-        $sumrating[$key] = 0;
-    }
-
-    foreach ($ratings as $rating) {
-        $sumrating[$rating]++;
-    }
-
-    $summary = "";
-    foreach ($scale as $key => $scaleitem) {
-        $summary = $sumrating[$key].$summary;
-        if ($key > 1) {
-            $summary = "/$summary";
-        }
-    }
-    return $summary;
-}
-
-/**
- * Print the menu of ratings as part of a larger form.
- * If the post has already been - set that value.
- *
- * @global object
- * @param int $postid
- * @param int $userid
- * @param array $scale is an array of ratings
- * @param int $myrating
- */
- //todo andrew remove this function
-function forum_print_rating_menu($postid, $userid, $scale, $myrating=NULL) {
-
-    static $strrate;
-    global $DB, $OUTPUT;
-
-    if (is_null($myrating)) {
-        if (!$rating = $DB->get_record("forum_ratings", array("userid" => $userid, "post" => $postid))) {
-            $myrating = FORUM_UNSET_POST_RATING;
-        } else {
-            $myrating = $rating->rating;
-        }
-    }
-
-    if (empty($strrate)) {
-        $strrate = get_string("rate", "forum");
-    }
-    $scale = array(FORUM_UNSET_POST_RATING => $strrate.'...') + $scale;
-    echo html_writer::select($scale, $postid, $myrating, false, array('class'=>'forumpostratingmenu'));
-}
-
-/**
  * Print the drop down that allows the user to select how they want to have
  * the discussion displayed.
  *
@@ -5755,6 +5177,7 @@
 function forum_print_discussion($course, $cm, $forum, $discussion, $post, $mode, $canreply=NULL, $canrate=false) {
 
     global $USER, $CFG, $DB, $PAGE, $OUTPUT;
+    require_once('../../rating/lib.php');
 
     if (isloggedin()) {
         $ownpost = ($USER->id == $post->userid);
@@ -5801,42 +5224,25 @@
         unset($postersgroups);
     }
 
-    $ratings = NULL;
-    $ratingsmenuused = false;
-    $ratingsformused = false;
-    if ($forum->assessed and isloggedin()) {
-        if ($scale = make_grades_menu($forum->scale)) {
-            $ratings =new object();
-            $ratings->scale = $scale;
-            $ratings->assesstimestart = $forum->assesstimestart;
-            $ratings->assesstimefinish = $forum->assesstimefinish;
-            $ratings->allow = $canrate;
-
-            if ($ratings->allow) {
-                echo '<form id="form" method="post" action="rate.php">';
-                echo '<div class="ratingform">';
-                echo '<input type="hidden" name="forumid" value="'.$forum->id.'" />';
-                echo '<input type="hidden" name="sesskey" value="'.sesskey().'" />';
-                $ratingsformused = true;
+    //load ratings
+    $ratingoptions = new stdclass();
+    $ratingoptions->context = $cm->context;
+    $ratingoptions->items = $posts;
+    $ratingoptions->aggregate = $forum->assessed;//the aggregation method
+    $ratingoptions->scaleid = $forum->scale;
+    $ratingoptions->userid = $USER->id;
+    if ($forum->type == 'single' or !$discussion->id) {
+        $ratingoptions->returnurl = "$CFG->wwwroot/mod/forum/view.php?id=$cm->id";
+    } else {
+        $ratingoptions->returnurl = "$CFG->wwwroot/mod/forum/discuss.php?d=$discussion->id";
             }
-          // preload all ratings - one query only and minimal memory
-            $cm->cache->ratings = array();
-            $cm->cache->myratings = array();
-            if ($postratings = forum_get_all_discussion_ratings($discussion)) {
-                foreach ($postratings as $pr) {
-                    if (!isset($cm->cache->ratings[$pr->postid])) {
-                        $cm->cache->ratings[$pr->postid] = array();
-                    }
-                    $cm->cache->ratings[$pr->postid][$pr->id] = $pr->rating;
-                    if ($pr->userid == $USER->id) {
-                        $cm->cache->myratings[$pr->postid] = $pr->rating;
-                    }
-                }
-                unset($postratings);
-            }
-        }
-    }
+    $ratingoptions->assesstimestart = $forum->assesstimestart;
+    $ratingoptions->assesstimefinish = $forum->assesstimefinish;
 
+    $rm = new rating_manager();
+    $posts = $rm->get_ratings($ratingoptions);
+
+
     $post->forum = $forum->id;   // Add the forum id to the post object, later used by forum_print_post
     $post->forumtype = $forum->type;
 
@@ -5844,51 +5250,25 @@
 
     $postread = !empty($post->postread);
 
-    if (forum_print_post($post, $discussion, $forum, $cm, $course, $ownpost, $reply, false, $ratings,
-                         '', '', $postread, true, $forumtracked)) {
-        $ratingsmenuused = true;
-    }
+    forum_print_post($post, $discussion, $forum, $cm, $course, $ownpost, $reply, false,
+                         '', '', $postread, true, $forumtracked);
 
     switch ($mode) {
         case FORUM_MODE_FLATOLDEST :
         case FORUM_MODE_FLATNEWEST :
         default:
-            if (forum_print_posts_flat($course, $cm, $forum, $discussion, $post, $mode, $ratings, $reply, $forumtracked, $posts)) {
-                $ratingsmenuused = true;
-            }
+            forum_print_posts_flat($course, $cm, $forum, $discussion, $post, $mode, $reply, $forumtracked, $posts);
             break;
 
         case FORUM_MODE_THREADED :
-            if (forum_print_posts_threaded($course, $cm, $forum, $discussion, $post, 0, $ratings, $reply, $forumtracked, $posts)) {
-                $ratingsmenuused = true;
-            }
+            forum_print_posts_threaded($course, $cm, $forum, $discussion, $post, 0, $reply, $forumtracked, $posts);
             break;
 
         case FORUM_MODE_NESTED :
-            if (forum_print_posts_nested($course, $cm, $forum, $discussion, $post, $ratings, $reply, $forumtracked, $posts)) {
-                $ratingsmenuused = true;
-            }
+            forum_print_posts_nested($course, $cm, $forum, $discussion, $post, $reply, $forumtracked, $posts);
             break;
     }
-
-    if ($ratingsformused) {
-        if ($ratingsmenuused) {
-            echo '<div class="ratingsubmit">';
-            echo '<input type="submit" id="forumpostratingsubmit" value="'.get_string('sendinratings', 'forum').'" />';
-            if (ajaxenabled() && !empty($CFG->forum_ajaxrating)) { /// AJAX enabled, standard submission form
-                $PAGE->requires->js_function_call('add_menu_listeners', array($OUTPUT->pix_url('i/loading_small')), true);
             }
-            if ($forum->scale < 0) {
-                if ($scale = $DB->get_record("scale", array("id" => abs($forum->scale)))) {
-                    echo $OUTPUT->help_icon_scale($course->id, $scale);
-                }
-            }
-            echo '</div>';
-        }
-        echo '</div>';
-        echo '</form>';
-    }
-}
 
 
 /**
@@ -5905,12 +5285,12 @@
  * @param bool $reply
  * @param bool $forumtracked
  * @param array $posts
+ * @return void
  */
 function forum_print_posts_flat($course, &$cm, $forum, $discussion, $post, $mode, $ratings, $reply, $forumtracked, $posts) {
     global $USER, $CFG;
 
     $link  = false;
-    $ratingsmenuused = false;
 
     if ($mode == FORUM_MODE_FLATNEWEST) {
         $sort = "ORDER BY created DESC";
@@ -5927,28 +5307,23 @@
 
         $postread = !empty($post->postread);
 
-        if (forum_print_post($post, $discussion, $forum, $cm, $course, $ownpost, $reply, $link, $ratings,
-                             '', '', $postread, true, $forumtracked)) {
-            $ratingsmenuused = true;
+        forum_print_post($post, $discussion, $forum, $cm, $course, $ownpost, $reply, $link, $ratings,
+                             '', '', $postread, true, $forumtracked);
         }
     }
 
-    return $ratingsmenuused;
-}
-
-
 /**
  * @todo Document this function
  *
  * @global object
  * @global object
  * @uses CONTEXT_MODULE
+ * @return void
  */
-function forum_print_posts_threaded($course, &$cm, $forum, $discussion, $parent, $depth, $ratings, $reply, $forumtracked, $posts) {
+function forum_print_posts_threaded($course, &$cm, $forum, $discussion, $parent, $depth, $reply, $forumtracked, $posts) {
     global $USER, $CFG;
 
     $link  = false;
-    $ratingsmenuused = false;
 
     if (!empty($posts[$parent->id]->children)) {
         $posts = $posts[$parent->id]->children;
@@ -5965,10 +5340,8 @@
 
                 $postread = !empty($post->postread);
 
-                if (forum_print_post($post, $discussion, $forum, $cm, $course, $ownpost, $reply, $link, $ratings,
-                                     '', '', $postread, true, $forumtracked)) {
-                    $ratingsmenuused = true;
-                }
+                forum_print_post($post, $discussion, $forum, $cm, $course, $ownpost, $reply, $link, $ratings,
+                                     '', '', $postread, true, $forumtracked);
             } else {
                 if (!forum_user_can_see_post($forum, $discussion, $post, NULL, $cm)) {
                     echo "</div>\n";
@@ -5993,25 +5366,22 @@
                 echo "</span>";
             }
 
-            if (forum_print_posts_threaded($course, $cm, $forum, $discussion, $post, $depth-1, $ratings, $reply, $forumtracked, $posts)) {
-                $ratingsmenuused = true;
-            }
+            forum_print_posts_threaded($course, $cm, $forum, $discussion, $post, $depth-1, $ratings, $reply, $forumtracked, $posts);
             echo "</div>\n";
         }
     }
-    return $ratingsmenuused;
 }
 
 /**
  * @todo Document this function
  * @global object
  * @global object
+ * @return void
  */
-function forum_print_posts_nested($course, &$cm, $forum, $discussion, $parent, $ratings, $reply, $forumtracked, $posts) {
+function forum_print_posts_nested($course, &$cm, $forum, $discussion, $parent, $reply, $forumtracked, $posts) {
     global $USER, $CFG;
 
     $link  = false;
-    $ratingsmenuused = false;
 
     if (!empty($posts[$parent->id]->children)) {
         $posts = $posts[$parent->id]->children;
@@ -6028,17 +5398,12 @@
             $post->subject = format_string($post->subject);
             $postread = !empty($post->postread);
 
-            if (forum_print_post($post, $discussion, $forum, $cm, $course, $ownpost, $reply, $link, $ratings,
-                                 '', '', $postread, true, $forumtracked)) {
-                $ratingsmenuused = true;
-            }
-            if (forum_print_posts_nested($course, $cm, $forum, $discussion, $post, $ratings, $reply, $forumtracked, $posts)) {
-                $ratingsmenuused = true;
-            }
+            forum_print_post($post, $discussion, $forum, $cm, $course, $ownpost, $reply, $link,
+                                 '', '', $postread, true, $forumtracked);
+            forum_print_posts_nested($course, $cm, $forum, $discussion, $post, $reply, $forumtracked, $posts);
             echo "</div>\n";
         }
     }
-    return $ratingsmenuused;
 }
 
 /**
@@ -7880,20 +7245,6 @@
 }
 
 /**
- * Returns array of forum aggregate types
- *
- * @return array
- */
-function forum_get_aggregate_types() {
-    return array (FORUM_AGGREGATE_NONE  => get_string('aggregatenone', 'forum'),
-                  FORUM_AGGREGATE_AVG   => get_string('aggregateavg', 'forum'),
-                  FORUM_AGGREGATE_COUNT => get_string('aggregatecount', 'forum'),
-                  FORUM_AGGREGATE_MAX   => get_string('aggregatemax', 'forum'),
-                  FORUM_AGGREGATE_MIN   => get_string('aggregatemin', 'forum'),
-                  FORUM_AGGREGATE_SUM   => get_string('aggregatesum', 'forum'));
-}
-
-/**
  * Returns array of forum layout modes
  *
  * @return array
Index: moodle/mod/forum/mod_form.php
--- moodle/mod/forum/mod_form.php Base (1.43)
+++ moodle/mod/forum/mod_form.php Locally Modified (Based On 1.43)
@@ -107,28 +107,6 @@
         }
 
 //-------------------------------------------------------------------------------
-        /*$mform->addElement('header', '', get_string('grade'));
-
-        $mform->addElement('select', 'assessed', get_string('aggregatetype', 'forum') , forum_get_aggregate_types());
-        $mform->setDefault('assessed', 0);
-        $mform->setHelpButton('assessed', array('assessaggregate', get_string('aggregatetype', 'forum'), 'forum'));
-
-        $mform->addElement('modgrade', 'scale', get_string('grade'), false);
-        $mform->disabledIf('scale', 'assessed', 'eq', 0);
-
-        $mform->addElement('checkbox', 'ratingtime', get_string('ratingtime', 'forum'));
-        $mform->disabledIf('ratingtime', 'assessed', 'eq', 0);
-
-        $mform->addElement('date_time_selector', 'assesstimestart', get_string('from'));
-        $mform->disabledIf('assesstimestart', 'assessed', 'eq', 0);
-        $mform->disabledIf('assesstimestart', 'ratingtime');
-
-        $mform->addElement('date_time_selector', 'assesstimefinish', get_string('to'));
-        $mform->disabledIf('assesstimefinish', 'assessed', 'eq', 0);
-        $mform->disabledIf('assesstimefinish', 'ratingtime');*/
-
-
-//-------------------------------------------------------------------------------
         $mform->addElement('header', '', get_string('blockafter', 'forum'));
         $options = array();
         $options[0] = get_string('blockperioddisabled','forum');
Index: moodle/mod/glossary/db/upgrade.php
--- moodle/mod/glossary/db/upgrade.php Base (1.34)
+++ moodle/mod/glossary/db/upgrade.php Locally Modified (Based On 1.34)
@@ -273,7 +273,7 @@
 
         //todo andrew drop glossary_ratings
 
-        //todo andrew set rating permissions based on current value of glossary.assessed
+        //do we want to set rating permissions based on current value of glossary.assessed?
 
         upgrade_mod_savepoint($result, 2010041300, 'glossary');
     }
Index: moodle/rating/index.php
--- moodle/rating/index.php Base (1.12)
+++ moodle/rating/index.php Locally Modified (Based On 1.12)
@@ -30,6 +30,7 @@
 $itemid   = required_param('itemid', PARAM_INT);
 $scaleid   = required_param('scaleid', PARAM_INT);
 $sort = optional_param('sort', '', PARAM_ALPHA);
+$popup = optional_param('popup', 0, PARAM_INT);//==1 if in a popup window?
 
 list($context, $course, $cm) = get_context_info_array($contextid);
 require_login($course, false, $cm);
@@ -39,6 +40,9 @@
     $url->param('sort', $sort);
 }
 $PAGE->set_url($url);
+if($popup) {
+    $PAGE->set_pagelayout('popup');
+}
 
 if ( !has_capability('moodle/rating:view',$context) ) {
     print_error('noviewrate', 'rating');
@@ -60,29 +64,30 @@
 $strname    = get_string('name');
 $strtime    = get_string('time');
 
-//Is there something more meaningful we can put in the title?
-//$PAGE->set_title("$strratings: ".format_string($post->subject));
+//Is there something more meaningful we can put in the title? It used to be forum post title
 $PAGE->set_title("$strratings: ".format_string($itemid));
 echo $OUTPUT->header();
 
-//if (!$ratings = forum_get_ratings($post->id, $sqlsort)) {
 $ratingoptions = new stdclass();
 $ratingoptions->context = $context;
 $ratingoptions->itemid = $itemid;
-$ratingoptions->sort = $sort;
+$ratingoptions->sort = $sqlsort;
 
 $rm = new rating_manager();
-$ratings = $rm->load_ratings_for_item($ratingoptions);
+$ratings = $rm->get_all_ratings_for_item($ratingoptions);
 if (!$ratings) {
-    //print_error('noresult', 'forum', '', format_string($post->subject));
-    print_error('noresult');
+    print_error('noresult', 'forum', '', format_string($itemid));
 } else {
+    $sortargs = "contextid=$contextid&amp;itemid=$itemid&amp;scaleid=$scaleid";
+    if($popup) {
+        $sortargs.="&amp;popup=$popup";
+    }
     echo "<table border=\"0\" cellpadding=\"3\" cellspacing=\"3\" class=\"generalbox\" style=\"width:100%\">";
     echo "<tr>";
     echo "<th class=\"header\" scope=\"col\">&nbsp;</th>";
-    echo "<th class=\"header\" scope=\"col\"><a href=\"report.php?id=$itemid&amp;sort=firstname\">$strname</a></th>";
-    echo "<th class=\"header\" scope=\"col\" style=\"width:100%\"><a href=\"report.php?id=$itemid&amp;sort=rating\">$strrating</a></th>";
-    echo "<th class=\"header\" scope=\"col\"><a href=\"report.php?id=$itemid&amp;sort=time\">$strtime</a></th>";
+    echo "<th class=\"header\" scope=\"col\"><a href=\"index.php?$sortargs&amp;sort=firstname\">$strname</a></th>";
+    echo "<th class=\"header\" scope=\"col\" style=\"width:100%\"><a href=\"index.php?$sortargs&amp;sort=rating\">$strrating</a></th>";
+    echo "<th class=\"header\" scope=\"col\"><a href=\"index.php?$sortargs&amp;sort=time\">$strtime</a></th>";
     echo "</tr>";
 
     foreach ($ratings as $rating) {
@@ -107,5 +112,7 @@
     echo "<br />";
 }
 
+if($popup) {
 echo $OUTPUT->close_window_button();
+}
 echo $OUTPUT->footer();
Index: moodle/rating/lib.php
--- moodle/rating/lib.php Base (1.12)
+++ moodle/rating/lib.php Locally Modified (Based On 1.12)
@@ -25,7 +25,7 @@
 
 define('RATING_UNSET_RATING', -999);
 
-//define ('RATING_AGGREGATE_NONE', 0); //no ratings
+define ('RATING_AGGREGATE_NONE', 0); //no ratings
 define ('RATING_AGGREGATE_AVERAGE', 1);
 define ('RATING_AGGREGATE_COUNT', 2);
 define ('RATING_AGGREGATE_MAXIMUM', 3);
@@ -107,16 +107,16 @@
         $ratingoptions = new stdclass();
         $ratingoptions->context = $this->context;
         $ratingoptions->items = $items;
-        $ratingoptions->aggregate = RATING_AGGREGATE_AVERAGE;//we dont actually care what aggregation is applied
+        $ratingoptions->aggregate = RATING_AGGREGATE_AVERAGE;//we dont actually care what aggregation method is applied
         $ratingoptions->scaleid = $this->scaleid;
         $ratingoptions->userid = $this->userid;
 
         $rm = new rating_manager();
-        $items = $rm->load_ratings($ratingoptions);
-        if( !isset($items[0]->rating) || !isset($items[0]->rating->id) ) {
+        $items = $rm->get_ratings($ratingoptions);
+        if( empty($items) || empty($items[0]->rating) || empty($items[0]->rating->id) ) {
             $data->contextid    = $this->context->id;
             $data->rating       = $rating;
-            $data->scaleid      = $this->scaleid;
+            $data->scaleid      = -$this->scaleid;//need to flip negativity. scale PKs are less than 0. remove after scales refactoring.
             $data->userid       = $this->userid;
             $data->itemid       = $this->itemid;
 
@@ -172,9 +172,14 @@
     * }
     * @return array an array of ratings
     */
-    public function load_ratings_for_item($options) {
+    public function get_all_ratings_for_item($options) {
         global $DB;
 
+        $sortclause = '';
+        if( !empty($options->sort) ) {
+            $sortclause = "ORDER BY $options->sort";
+        }
+
         $userfields = user_picture::fields('u','uid');
         $sql = "SELECT r.id, r.rating, r.itemid, r.userid, r.timemodified,
                     $userfields
@@ -182,7 +187,7 @@
                 LEFT JOIN {user} u ON r.userid = u.id
                 WHERE r.contextid = :contextid AND
                       r.itemid  = :itemid
-                {$options->sort}";
+                {$sortclause}";
 
         $params['contextid'] = $options->context->id;
         $params['itemid'] = $options->itemid;
@@ -200,17 +205,21 @@
     *            scaleid => int the scale from which the user can select a rating [required]
     *            userid => int the id of the current user [optional]
     *            returnurl => string the url to return the user to after submitting a rating. Can be left null for ajax requests [optional]
+    *            assesstimestart => int only allow rating of items created after this timestamp [optional]
+    *            assesstimefinish => int only allow rating of items created before this timestamp [optional]
     * @return array the array of items with their ratings attached at $items[0]->rating
     */
-    public function load_ratings($options) {
+    public function get_ratings($options) {
         global $DB, $USER, $PAGE, $CFG;
 
         if(empty($options->items)) {
             return $options->items;
         }
 
-        if (is_null($options->userid)) {
+        if (empty($options->userid)) {
             $userid = $USER->id;
+        } else {
+            $userid = $options->userid;
         }
 
         $aggregatestr = $this->get_aggregation_method($options->aggregate);
@@ -241,7 +250,7 @@
     GROUP BY r.itemid, ur.rating, ur.id, ur.userid, ur.scaleid
     ORDER BY r.itemid";
 
-        $params['userid'] = $options->userid;
+        $params['userid'] = $userid;
         $params['contextid'] = $options->context->id;
 
         $ratingsrecords = $DB->get_records_sql($sql, $params);
@@ -251,15 +260,26 @@
         $scalemax = null;
 
         //we could look for a scale id on each item to allow each item to use a different scale
-
         if($options->scaleid < 0 ) { //if its a scale (not numeric)
             $scalerecord = $DB->get_record('scale', array('id' => -$options->scaleid));
             if ($scalerecord) {
-                $scaleobj->scaleitems = explode(',', $scalerecord->scale);
-                $scaleobj->id = $scalerecord->id;
+                $scalearray = explode(',', $scalerecord->scale);
+
+                //is there a more efficient way to get the indexes to start at 1 instead of 0?
+                //this will go away when scales are refactored
+                $c = count($scalearray);
+                $n = null;
+                for($i=0; $i<$c; $i++) {
+                    $n = $i+1;
+                    $scaleobj->scaleitems["$n"] = $scalearray[$i];//treat index as a string to allow sorting without changing the value
+                }
+                krsort($scaleobj->scaleitems);//have the highest grade scale item appear first
+
+                $scaleobj->id = $options->scaleid;//dont use the one from the record or we "forget" that its negative
                 $scaleobj->name = $scalerecord->name;
+                $scaleobj->courseid = $scalerecord->courseid;
 
-                $scalemax = count($scaleobj->scale)-1;
+                $scalemax = count($scaleobj->scaleitems);
             }
         }
         else { //its numeric
@@ -278,6 +298,14 @@
             $settings->returnurl = $options->returnurl;
         }
 
+        $settings->assesstimestart = $settings->assesstimefinish = null;
+        if( !empty($options->assesstimestart) ) {
+            $settings->assesstimestart = $options->assesstimestart;
+        }
+        if( !empty($options->assesstimefinish) ) {
+            $settings->assesstimefinish = $options->assesstimefinish;
+        }
+
         $settings->permissions = new stdclass();
         $settings->permissions->canview = has_capability('moodle/rating:view',$options->context);
         $settings->permissions->canviewall = has_capability('moodle/rating:viewall',$options->context);
@@ -302,6 +330,15 @@
                     $rating->aggregate  = $rec->aggrrating; //unset($rec->aggrrating);
                     $rating->count      = $rec->numratings; //unset($rec->numratings);
                     $rating->rating     = $rec->usersrating; //unset($rec->usersrating);
+                    if( !empty($item->created) ) {
+                        $rating->itemtimecreated = $item->created;//the forum_posts table has created instead of timecreated
+                    }
+                    else if(!empty($item->timecreated)) {
+                        $rating->itemtimecreated = $item->timecreated;
+                    }
+                    else {
+                        $rating->itemtimecreated = null;
+                    }
                     break;
                 }
             }
@@ -320,8 +357,14 @@
                 $rating->itemid     = $item->id;
                 $rating->userid     = null;
                 $rating->scaleid     = null;
+                $rating->itemtimecreated = null;
             }
 
+            if( !empty($item->userid) ) {
+                $rating->itemuserid = $item->userid;
+            } else {
+                $rating->itemuserid = null;
+            }
             $rating->settings = $settings;
             $item->rating = $rating;
 
@@ -332,16 +375,119 @@
             if ($rating->rating > $scalemax) {
                 $rating->rating = $scalemax;
             }
+            if ($rating->aggregate > $scalemax) {
+                $rating->aggregate = $scalemax;
         }
+        }
+
         return $options->items;
     }
 
     /**
+    * Returns an array of grades calculated by aggregating item ratings.
+    * @param object $options {
+    *            userid => int the id of the user whose items have been rated. NOT the user who submitted the ratings [required]
+    *            aggregationmethod => int the aggregation method to apply when calculating grades ie RATING_AGGREGATE_AVERAGE [required]
+    *            scaleid => int the scale from which the user can select a rating. Used for bounds checking. [required]
+    *            itemtable => int the table containing the items [required]
+    *            itemtableusercolum => int the column of the user table containing the item owner's user id [required]
+    *
+    *            contextid => int the context in which the rated items exist [optional]
+    *
+    *            modulename => string the name of the module [optional]
+    *            moduleid => int the id of the module instance [optional]
+    *
+    * @return array the array of the user's grades
+    */
+    public function get_user_grades($options) {
+        global $DB;
+
+        $modulename = $options->modulename;
+        $moduleid   = $options->moduleid;
+        $cmidnumber = $options->cmidnumber; //not using this but maybe we should be
+
+        $contextid = null;
+
+        //if the calling code doesn't supply a context id we'll have to figure it out
+        if( !empty($options->contextid) ) {
+            $contextid = $options->contextid;
+        }
+        //else if( !empty($options->cmid) ) {
+            //not implemented. Is there a convenient way to get a context id from a cm id?
+        //}
+        else {
+            //get the context id
+            //Is this correct? Will we ever want to rate and grade something outside of the module context?
+            //going to the db for this seems wrong
+            list($ctxselect, $ctxjoin) = context_instance_preload_sql('cm.id', CONTEXT_MODULE, 'ctx');
+            $sql = "SELECT cm.* $ctxselect
+            FROM {course_modules} cm
+            LEFT JOIN {modules} mo ON mo.id = cm.module
+            LEFT JOIN {{$modulename}} m ON m.id = cm.instance $ctxjoin
+            WHERE mo.name=:modulename AND m.id=:moduleid";
+            $contextrecord = $DB->get_record_sql($sql, array('modulename'=>$modulename, 'moduleid'=>$moduleid), '*', MUST_EXIST);
+            $contextid = $contextrecord->ctxid;
+        }
+
+        $params = array();
+        $params['contextid']= $contextid;
+        $itemtable          = $options->itemtable;
+        $itemtableusercolumn= $options->itemtableusercolumn;
+        $scaleid            = $options->scaleid;
+        $params['userid1'] = $params['userid2'] = $params['userid3']  = $options->userid;
+
+        $aggregationstring = $this->get_aggregation_method($options->aggregationmethod);
+
+        $sql = "SELECT :userid1 as id, :userid2 AS userid, $aggregationstring(r.rating) AS rawgrade
+                FROM mdl_rating r
+                WHERE r.contextid=:contextid 
+                    AND r.itemid IN (SELECT i.id AS itemid FROM {{$itemtable}} i WHERE i.{$itemtableusercolumn} = :userid3)";
+
+        $results = $DB->get_records_sql($sql, $params);
+        if ($results) {
+            // it could throw off the grading if count and sum returned a rawgrade higher than scale
+            // so to prevent it we review the results and ensure that rawgrade does not exceed the scale, if it does we set rawgrade = scale (i.e. full credit)
+            foreach ($results as $rid=>$result) {
+                if ($options->scaleid >= 0) {
+                    //numeric
+                    if ($result->rawgrade > $options->scaleid) {
+                        $results[$rid]->rawgrade = $options->scaleid;
+                    }
+                } else {
+                    //scales
+                    if ($scale = $DB->get_record('scale', array('id' => -$options->scaleid))) {
+                        $scale = explode(',', $scale->scale);
+                        $max = count($scale);
+                        if ($result->rawgrade > $max) {
+                            $results[$rid]->rawgrade = $max;
+                        }
+                    }
+                }
+            }
+        }
+        return $results;
+    }
+
+    /**
+     * Returns array of aggregate types. Used by ratings.
+     *
+     * @return array
+     */
+    public function get_aggregate_types() {
+        return array (RATING_AGGREGATE_NONE  => get_string('aggregatenone', 'forum'),
+                      RATING_AGGREGATE_AVERAGE   => get_string('aggregateavg', 'forum'),
+                      RATING_AGGREGATE_COUNT => get_string('aggregatecount', 'forum'),
+                      RATING_AGGREGATE_MAXIMUM   => get_string('aggregatemax', 'forum'),
+                      RATING_AGGREGATE_MINIMUM   => get_string('aggregatemin', 'forum'),
+                      RATING_AGGREGATE_SUM   => get_string('aggregatesum', 'forum'));
+    }
+
+    /**
     * Converts an aggregation method constant into something that can be included in SQL
     * @param int $aggregate An aggregation constant. For example, RATING_AGGREGATE_AVERAGE.
     * @return string an SQL aggregation method
     */
-    private function get_aggregation_method($aggregate) {
\ No newline at end of file
+    public function get_aggregation_method($aggregate) {
\ No newline at end of file
         $aggregatestr = null;
         switch($aggregate){
             case RATING_AGGREGATE_AVERAGE:
Index: moodle/rating/module.js
--- moodle/rating/module.js Base (1.3)
+++ moodle/rating/module.js Locally Modified (Based On 1.3)
@@ -34,16 +34,23 @@
             on : {
                 complete : function(tid, outcome, args) {
                     try {
-                        outcome = this.Y.JSON.parse(outcome.responseText);
+                        var responseobj = this.Y.JSON.parse(outcome.responseText);
+                        var itemid = responseobj.itemid;
+
+                        var node = this.Y.one('#ratingaggregate'+itemid);
+                        node.set('innerHTML',responseobj.aggregate);
+
+                        var node = this.Y.one('#ratingcount'+itemid);
+                        node.set('innerHTML',"("+responseobj.count+")");
                     } catch(e) {
-                        //this.form.submit();
-                        alert(outcome.responseText);
+                        //todo put up an overlay or similar rather than an alert
+                        alert(e.message+" "+outcome.responseText);
                     }
                     if(outcome.success){
                         //do nothing
                     }
                     else if (outcome.error){
-                        //todo andrew put up an overlay or similar rather than an alert
+                        //todo put up an overlay or similar rather than an alert
\ No newline at end of file
                         alert(outcome.error);
                     }
                 }
Index: moodle/rating/rate.php
--- moodle/rating/rate.php Base (1.8)
+++ moodle/rating/rate.php Locally Modified (Based On 1.8)
@@ -32,7 +32,8 @@
 $itemid = required_param('itemid', PARAM_INT);
 $scaleid = required_param('scaleid', PARAM_INT);
 $userrating = required_param('rating', PARAM_INT);
-$returnurl = required_param('returnurl', null, PARAM_LOCALURL);//required for non-ajax requests
+$rateduserid = required_param('rateduserid', PARAM_INT);//which user is being rated. Required to update their grade
+$returnurl = required_param('returnurl', PARAM_LOCALURL);//required for non-ajax requests
 
 $result = new stdClass;
 
@@ -66,4 +67,19 @@
 
 $rating->update_rating($userrating);
 
-redirect($CFG->wwwroot.'/'.$returnurl);
\ No newline at end of file
+//todo add a setting to turn grade updating off for those who don't want them in gradebook
+//note that this needs to be done in both rate.php and rate_ajax.php
+if(true){
+    //tell the module that its grades have changed
+    if (!$modinstance = $DB->get_record($cm->modname, array('id' => $cm->instance))) {
+        print_error('invalidid');
+    }
+    $modinstance->cmidnumber = $cm->id; //MDL-12961
+    $functionname = $cm->modname.'_update_grades';
+    require_once("../mod/{$cm->modname}/lib.php");
+    if(function_exists($functionname)) {
+        $functionname($modinstance, $rateduserid);
+    }
+}
+
+redirect($returnurl);
\ No newline at end of file
Index: moodle/rating/rate_ajax.php
--- moodle/rating/rate_ajax.php Base (1.1)
+++ moodle/rating/rate_ajax.php Locally Modified (Based On 1.1)
@@ -32,6 +32,8 @@
 $itemid = required_param('itemid', PARAM_INT);
 $scaleid = required_param('scaleid', PARAM_INT);
 $userrating = required_param('rating', PARAM_INT);
+$rateduserid = required_param('rateduserid', PARAM_INT);//which user is being rated. Required to update their grade
+$aggregationmethod = optional_param('aggregation', PARAM_INT);//we're going to calculate the aggregate and return it to the client
 
 $result = new stdClass;
 
@@ -71,6 +73,47 @@
 
 $rating->update_rating($userrating);
 
+//todo add a setting to turn grade updating off for those who don't want them in gradebook
+//note that this needs to be done in both rate.php and rate_ajax.php
+if(true){
+    //tell the module that its grades have changed
+    if ( $modinstance = $DB->get_record($cm->modname, array('id' => $cm->instance)) ) {
+        $modinstance->cmidnumber = $cm->id; //MDL-12961
+        $functionname = $cm->modname.'_update_grades';
+        require_once("../mod/{$cm->modname}/lib.php");
+        if(function_exists($functionname)) {
+            $functionname($modinstance, $rateduserid);
+        }
+    }
+}
+
+//need to retrieve the updated item to get its new aggregate value
+$item = new stdclass();
+$item->id = $rating->itemid;
+$items = array($item);
+
+//most of $ratingoptions variables are set correctly
+$ratingoptions->items = $items;
+$ratingoptions->aggregate = $aggregationmethod;
+
+$rm = new rating_manager();
+$items = $rm->get_ratings($ratingoptions);
+
+//for custom scales return text not the value
+//this scales weirdness will go away when scales are refactored
+$scalearray = null;
+$aggregatetoreturn = round($items[0]->rating->aggregate,1);
+if($rating->scaleid < 0 ) { //if its a scale (not numeric)
+    $scalerecord = $DB->get_record('scale', array('id' => -$rating->scaleid));
+    if ($scalerecord) {
+        $scalearray = explode(',', $scalerecord->scale);
+    }
+    $aggregatetoreturn = $scalearray[$aggregatetoreturn-1];
+}
+
 $result = new stdClass;
 $result->success = true;
+$result->aggregate = $aggregatetoreturn;
+$result->count = $items[0]->rating->count;
+$result->itemid = $rating->itemid;
\ No newline at end of file
 echo json_encode($result);
