]> git.mjollnir.org Git - moodle.git/commitdiff
MDL-17364 forum ajax rating working
authorstronk7 <stronk7>
Sat, 17 Jan 2009 19:14:37 +0000 (19:14 +0000)
committerstronk7 <stronk7>
Sat, 17 Jan 2009 19:14:37 +0000 (19:14 +0000)
mod/forum/discuss.php
mod/forum/lib.php
mod/forum/rate.php
mod/forum/rate_ajax.js [new file with mode: 0644]
mod/forum/rate_ajax.php [new file with mode: 0644]
mod/forum/settings.php

index 745bc6060840ab0586bcc65866ba56ca951fde45..46ef0ec7f6abd62e6ec9fe776e517655f80dc2af 100644 (file)
 
     require_course_login($course, true, $cm);
 
+/// Add ajax-related libs
+    require_js(array('yui_yahoo', 'yui_event', 'yui_dom', 'yui_connection', 'yui_json'));
+    require_js('mod/forum/rate_ajax.js');
+
     // move this down fix for MDL-6926
     require_once('lib.php');
 
index 955638e4e7b19903299234649b557e44e0c2170d..c8c229b9364e8ab76bb8b5afbe22c5a1b76fb856 100644 (file)
@@ -3257,7 +3257,9 @@ function forum_print_post($post, $discussion, $forum, &$cm, $course, $ownpost=fa
             }
 
             if ($canviewallratings and !$mypost) {
-                forum_print_ratings($post->id, $ratings->scale, $forum->assessed, $canviewallratings, $allratings);
+                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);
@@ -3265,7 +3267,9 @@ function forum_print_post($post, $discussion, $forum, &$cm, $course, $ownpost=fa
                 }
 
             } else if ($mypost) {
-                forum_print_ratings($post->id, $ratings->scale, $forum->assessed, true, $allratings);
+                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);
@@ -3489,7 +3493,7 @@ function forum_shorten_post($message) {
  * Forumid prevents the double lookup of the forumid in discussion to determine the aggregate type
  * Scale is an array of ratings
  */
-function forum_print_ratings($postid, $scale, $aggregatetype, $link=true, $ratings=null) {
+function forum_print_ratings($postid, $scale, $aggregatetype, $link=true, $ratings=null, $return=false) {
 
     $strratings = '';
 
@@ -3522,11 +3526,18 @@ function forum_print_ratings($postid, $scale, $aggregatetype, $link=true, $ratin
             $strratings = get_string("ratings", "forum");
         }
 
-        echo "$strratings: ";
+        $strratings .= ': ';
+
         if ($link) {
-            link_to_popup_window ("/mod/forum/report.php?id=$postid", "ratings", $agg, 400, 600);
+            $strratings .= link_to_popup_window ("/mod/forum/report.php?id=$postid", "ratings", $agg, 400, 600, null, null, true);
         } else {
-            echo "$agg ";
+            $strratings .= "$agg ";
+        }
+
+        if ($return) {
+            return $strratings;
+        } else {
+            echo $strratings;
         }
     }
 }
@@ -3770,7 +3781,7 @@ function forum_print_rating_menu($postid, $userid, $scale, $myrating=NULL) {
         $strrate = get_string("rate", "forum");
     }
     $scale = array(FORUM_UNSET_POST_RATING => $strrate.'...') + $scale;
-    choose_from_menu($scale, $postid, $myrating, '');
+    choose_from_menu($scale, $postid, $myrating, '', '', '0', false, false, 0, '', false, false, 'forumpostratingmenu');
 }
 
 /**
@@ -5318,7 +5329,10 @@ function forum_print_discussion($course, $cm, $forum, $discussion, $post, $mode,
     if ($ratingsformused) {
         if ($ratingsmenuused) {
             echo '<div class="ratingsubmit">';
-            echo '<input type="submit" value="'.get_string('sendinratings', 'forum').'" />';
+            echo '<input type="submit" id="forumpostratingsubmit" value="'.get_string('sendinratings', 'forum').'" />';
+            if (ajaxenabled() && !empty($CFG->forum_ajaxrating)) { /// AJAX enabled, standard submission form
+                print_js_call('init_rate_ajax');
+            }
             if ($forum->scale < 0) {
                 if ($scale = $DB->get_record("scale", array("id" => abs($forum->scale)))) {
                     print_scale_menu_helpbutton($course->id, $scale );
index c0e6e6582bf99c8adf8088bf3ab1cfb0ccdaccc3..1879f4d34bc9838869511b8ef6674eea0f1a1be5 100644 (file)
@@ -2,6 +2,7 @@
 
 //  Collect ratings, store them, then return to where we came from
 
+/// TODO: Centralise duplicate code in rate.php and rate_ajax.php
 
     require_once('../../config.php');
     require_once('lib.php');
diff --git a/mod/forum/rate_ajax.js b/mod/forum/rate_ajax.js
new file mode 100644 (file)
index 0000000..7f4fb3d
--- /dev/null
@@ -0,0 +1,168 @@
+// $Id$
+
+///////////////////////////////////////////////////////////////////////////
+//                                                                       //
+// 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_rate_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) {
+
+    /** hide the submit button */
+    var submitbutton = YAHOO.util.Dom.get('forumpostratingsubmit');
+    submitbutton.style.display = 'none';
+
+    /** prevent form submission **/
+    var form = YAHOO.util.Dom.get('form');
+    YAHOO.util.Event.addListener(form, 'submit', prevent_form_submission);
+
+    /** add listeners to all rating menus */
+    var menus = YAHOO.util.Dom.getElementsByClassName('forumpostratingmenu', 'select');
+    for (var i=0; i<menus.length; i++) {
+        var menu = menus[i];
+        YAHOO.util.Event.addListener(menu, 'change', perform_rate, menu);
+    }
+}
+
+/**
+ * This function prevents manual form submission, to avoid
+ * rate form to be submitted completely
+ */
+function prevent_form_submission(e) {
+
+    /** stop submission completely **/
+    YAHOO.util.Event.stopEvent(e);
+}
+
+/**
+ * This function performs the communication with the server
+ * in order to send new rates and receive feedback about that.
+ * It's the action thrown by all the menu listeners defined above
+ */
+function perform_rate(e, menu) {
+
+    /** define response behaviour **/
+    var callback = {
+        success: rate_success,
+        failure: rate_failure,
+        args:menu
+    };
+
+    /** Here goes the request **/
+    var url = moodle_cfg.wwwroot +  '/mod/forum/rate_ajax.php?postid=' + menu.name + '&rate=' + menu.value + '&sesskey=' + moodle_cfg.sesskey;
+    YAHOO.util.Connect.asyncRequest('GET', url, callback, null);
+
+    /** Start animation **/
+    var animatedElement   = YAHOO.util.Dom.getAncestorByTagName(menu, 'div');
+    animatedElement.style.background = "url('" + moodle_cfg.pixpath + "/i/loading_small.gif') no-repeat top right";
+
+}
+
+/**
+ * Code to execute when we receive a success in the AJAX response
+ * It should print updated info about ratings (replacing previous one)
+ */
+function rate_success(o) {
+    menu = this.args;
+
+    /** Stop animation **/
+    var animatedElement   = YAHOO.util.Dom.getAncestorByTagName(menu, 'div');
+    animatedElement.style.background = '';
+
+    /** Parse json response **/
+    var response = new Object();
+    try {
+        response = YAHOO.lang.JSON.parse(o.responseText);
+    } catch (e) { /** Fake response **/
+        response.status = 'Error';
+        response.message= '';
+    }
+
+    /** Process error response **/
+    if (response.status != 'Ok') {
+        display_error(menu, reponse);
+    } else {
+        display_response(menu, response);
+    }
+
+    /** That's all, really simple **/
+}
+
+/**
+ * Code to execute when we receive a failure in the AJAX response
+ * It should print some error message
+ */
+function rate_failure(o) {
+    menu = this.args;
+
+    /** Stop animation **/
+    var animatedElement   = YAHOO.util.Dom.getAncestorByTagName(menu, 'div');
+    animatedElement.style.background = '';
+
+    /** Process error response **/
+    display_error(menu);
+}
+
+/**
+ * This function will display the correct response received from server
+ */
+function display_response(menu, response) {
+
+    /** Process ok response, displaying it **/
+    var ratingsDiv  = YAHOO.util.Dom.getAncestorByTagName(menu, 'div');
+    var ratingsSpan = YAHOO.util.Dom.getFirstChildBy(ratingsDiv, function(el){return el.getAttribute('class') == 'forumpostratingtext';});
+
+    /** span doesn't exist (first rate), add it, shouldn't happen ever but... **/
+    if (!ratingsSpan) {
+        var ratingsSpan = document.createElement('span');
+        YAHOO.util.Dom.addClass(ratingsSpan, 'forumpostratingtext');
+        ratingsDiv.appendChild(ratingsSpan);
+    }
+
+    /** finally replace span HTML **/
+    ratingsSpan.innerHTML = response.message;
+}
+
+/**
+ * This function will perform the desired actions to inform
+ * about the error response of ajax request
+ */
+function display_error(menu, response) {
+    /** Set red background color in menu - silly error measure **/
+    menu.style.backgroundColor = 'red';
+}
+
diff --git a/mod/forum/rate_ajax.php b/mod/forum/rate_ajax.php
new file mode 100644 (file)
index 0000000..8c3e7d4
--- /dev/null
@@ -0,0 +1,160 @@
+<?php // $Id$
+
+///////////////////////////////////////////////////////////////////////////
+//                                                                       //
+// 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                         //
+//                                                                       //
+///////////////////////////////////////////////////////////////////////////
+
+/// Accept, process and reply to ajax calls to rate forums
+
+/// TODO: Centralise duplicate code in rate.php and rate_ajax.php
+
+    require_once('../../config.php');
+    require_once($CFG->dirroot . '/mod/forum/lib.php');
+
+/// 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;
+    }
+
+/// Here we maintain response contents
+    $response = array('status'=> 'Error', 'message'=>'kk');
+
+/// Check access.
+    if (!isloggedin()) {
+        print_error('mustbeloggedin');
+    }
+    if (isguestuser()) {
+        print_error('noguestrate', 'forum');
+    }
+    if (!confirm_sesskey()) {
+        print_error('invalidsesskey');
+    }
+
+
+/// Check required params
+    $postid = required_param('postid', PARAM_INT); // The postid to rate
+    $rate   = required_param('rate', PARAM_INT); // The rate to apply
+
+/// Check postid is valid
+    if (!$post = $DB->get_record_sql('SELECT p.*,
+                                             d.forum AS forumid
+                                        FROM {forum_posts} p
+                                        JOIN {forum_discussions} d ON p.discussion = d.id
+                                       WHERE p.id = ?', array($postid))) {
+        print_error('invalidpostid', 'forum', '', $postid);;
+    }
+
+/// Check forum
+    if (!$forum = $DB->get_record('forum', array('id' => $post->forumid))) {
+        print_error('invalidforumid', 'forum');
+    }
+
+/// Check course
+    if (!$course = $DB->get_record('course', array('id' => $forum->course))) {
+        print_error('invalidcourseid');
+    }
+
+/// Check coursemodule
+    if (!$cm = get_coursemodule_from_instance('forum', $forum->id)) {
+        print_error('invalidcoursemodule');
+    } else {
+        $forum->cmidnumber = $cm->id; //MDL-12961
+    }
+
+/// Check forum can be rated
+    if (!$forum->assessed) {
+        print_error('norate', 'forum');
+    }
+
+/// Check user can rate
+    $context = get_context_instance(CONTEXT_MODULE, $cm->id);
+    require_capability('mod/forum:rate', $context);
+
+/// Check timed ratings
+    if ($forum->assesstimestart and $forum->assesstimefinish) {
+        if ($post->created < $forum->assesstimestart or $post->created > $forum->assesstimefinish) {
+            // we can not rate this, ignore it - this should not happen anyway unless teacher changes setting
+            print_error('norate', 'forum');
+        }
+    }
+
+/// Calculate scale values
+    $scale_values = make_grades_menu($forum->scale);
+
+/// Check rate is valid for for that forum scale values
+    if (!array_key_exists($rate, $scale_values) && $rate != FORUM_UNSET_POST_RATING) {
+        print_error('invalidrate', 'forum');
+    }
+
+/// Everything ready, process rate
+
+/// Deleting rate
+    if ($rate == FORUM_UNSET_POST_RATING) {
+        $DB->delete_records('forum_ratings', array('post' => $postid, 'userid' => $USER->id));
+
+/// Updating rate
+    } else if ($oldrating = $DB->get_record('forum_ratings', array('userid' => $USER->id, 'post' => $post->id))) {
+        if ($rate != $oldrating->rating) {
+            $oldrating->rating = $rate;
+            $oldrating->time   = time();
+            if (!$DB->update_record('forum_ratings', $oldrating)) {
+                print_error('cannotupdaterate', 'error', '', (object)array('id'=>$post->id, 'rating'=>$rate));
+            }
+        }
+
+/// Inserting rate
+    } else {
+        $newrating = new object();
+        $newrating->userid = $USER->id;
+        $newrating->time   = time();
+        $newrating->post   = $post->id;
+        $newrating->rating = $rate;
+
+        if (! $DB->insert_record('forum_ratings', $newrating)) {
+            print_error('cannotinsertrate', 'error', '', (object)array('id'=>$postid, 'rating'=>$rate));
+        }
+    }
+
+/// Update grades
+    forum_update_grades($forum, $post->userid);
+
+/// Check user can see any rate
+    $canviewanyrating = has_capability('mod/forum:viewanyrating', $context);
+
+/// Decide if rates info is displayed
+    $rateinfo = '';
+    if ($canviewanyrating) {
+        $rateinfo = forum_print_ratings($postid, $scale_values, $forum->assessed, true, NULL, true);
+    }
+
+/// Calculate response
+    $response['status']  = 'Ok';
+    $response['message'] = $rateinfo;
+    echo json_encode($response);
+
+?>
index 6c5b1b2561f3e655144664dde3e6212e99c5403a..c70a885b7d1a0be11e42a77d610ef56f35c30f20 100644 (file)
@@ -65,4 +65,7 @@ $settings->add(new admin_setting_configcheckbox('forum_enabletimedposts', get_st
 $settings->add(new admin_setting_configcheckbox('forum_logblocked', get_string('logblocked', 'forum'),
                    get_string('configlogblocked', 'forum'), 1));
 
+$settings->add(new admin_setting_configcheckbox('forum_ajaxrating', get_string('ajaxrating', 'forum'),
+                   get_string('configajaxrating', 'forum'), 0));
+
 ?>