Skip to content
Browse files

MDL-26838 rating: remove logged in users ability to sidestep rating v…

…alidity checks
  • Loading branch information...
1 parent eb9d692 commit 4af7c9d188da683780aa6494775b97b659e62dda @andyjdavis andyjdavis committed Apr 1, 2011
Showing with 314 additions and 87 deletions.
  1. +1 −0 lang/en/rating.php
  2. +4 −0 lib/outputrenderers.php
  3. +73 −4 mod/data/lib.php
  4. +1 −2 mod/data/view.php
  5. +88 −7 mod/forum/lib.php
  6. +1 −0 mod/forum/user.php
  7. +58 −5 mod/glossary/lib.php
  8. +1 −2 mod/glossary/view.php
  9. +39 −29 rating/lib.php
  10. +25 −20 rating/rate.php
  11. +23 −18 rating/rate_ajax.php
View
1 lang/en/rating.php
@@ -50,6 +50,7 @@
$string['rate'] = 'Rate';
$string['ratepermissiondenied'] = 'You do not have permission to rate this item';
$string['rating'] = 'Rating';
+$string['ratinginvalid'] = 'Rating is invalid';
$string['ratingtime'] = 'Restrict ratings to items with dates in this range:';
$string['ratings'] = 'Ratings';
$string['rolewarning'] = 'Roles with permission to rate';
View
4 lib/outputrenderers.php
@@ -1526,6 +1526,10 @@ function render_rating(rating $rating) {
$attributes = array('type'=>'hidden', 'class'=>'ratinginput', 'name'=>'contextid', 'value'=>$rating->context->id);
$formstart .= html_writer::empty_tag('input', $attributes);
+ $attributes['name'] = 'component';
+ $attributes['value'] = $rating->settings->component;
+ $formstart .= html_writer::empty_tag('input', $attributes);
+
$attributes['name'] = 'itemid';
$attributes['value'] = $rating->itemid;
$formstart .= html_writer::empty_tag('input', $attributes);
View
77 mod/data/lib.php
@@ -1369,11 +1369,80 @@ function data_rating_permissions($options) {
}
/**
- * Returns the names of the table and columns necessary to check items for ratings
- * @return array an array containing the item table, item id and user id columns
+ * Validates a submitted rating
+ * @param array $params submitted data
+ * context => object the context in which the rated items exists [required]
+ * itemid => int the ID of the object being rated
+ * scaleid => int the scale from which the user can select a rating. Used for bounds checking. [required]
+ * rating => int the submitted rating
+ * rateduserid => int the id of the user whose items have been rated. NOT the user who submitted the ratings. 0 to update all. [required]
+ * aggregation => int the aggregation method to apply when calculating grades ie RATING_AGGREGATE_AVERAGE [required]
+ * @return boolean true if the rating is valid
*/
-function data_rating_item_check_info() {
- return array('data_records','id','userid');
+function data_rating_add($params) {
+ global $DB, $USER;
+
+ if (!array_key_exists('itemid', $params) || !array_key_exists('context', $params)) {
+ debugging('itemid or context not supplied');
+ return false;
+ }
+
+ $datasql = "SELECT d.id as did, d.course, r.userid as userid, d.approval, r.approved, r.timecreated, d.assesstimestart, d.assesstimefinish, r.groupid
+ FROM {data_records} r
+ JOIN {data} d ON r.dataid = d.id
+ WHERE r.id = :itemid";
+ $dataparams = array('itemid'=>$params['itemid']);
+ if (!$info = $DB->get_record_sql($datasql, $dataparams)) {
+ //item id doesn't exist
+ return false;
+ }
+
+ if ($info->userid == $USER->id) {
+ //user is attempting to rate their own glossary entry
+ return false;
+ }
+
+ if ($info->approval && !$info->approved) {
+ //database requires approval but this item isnt approved
+ return false;
+ }
+
+ //check the item we're rating was created in the assessable time window
+ if (!empty($info->assesstimestart) && !empty($info->assesstimefinish)) {
+ if ($info->timecreated < $info->assesstimestart || $info->timecreated > $info->assesstimefinish) {
+ return false;
+ }
+ }
+
+ $dataid = $info->did;
+ $groupid = $info->groupid;
+ $courseid = $info->course;
+
+ $cm = get_coursemodule_from_instance('data', $dataid);
+ if (empty($cm)) {
+ return false;
+ }
+ $context = get_context_instance(CONTEXT_MODULE, $cm->id);
+
+ //if the supplied context doesnt match the item's context
+ if (empty($context) || $context->id != $params['context']->id) {
+ return false;
+ }
+
+ // Make sure groups allow this user to see the item they're rating
+ $course = $DB->get_record('course', array('id'=>$courseid), '*', MUST_EXIST);
+ if ($groupid > 0 and $groupmode = groups_get_activity_groupmode($cm, $course)) { // Groups are being used
+ if (!groups_group_exists($groupid)) { // Can't find group
+ return false;//something is wrong
+ }
+
+ if (!groups_is_member($groupid) and !has_capability('moodle/site:accessallgroups', $context)) {
+ // do not allow rating of posts from other groups when in SEPARATEGROUPS or VISIBLEGROUPS
+ return false;
+ }
+ }
+
+ return true;
}
View
3 mod/data/view.php
@@ -667,15 +667,14 @@
if ($data->assessed!=RATING_AGGREGATE_NONE) {
$ratingoptions = new stdclass();
$ratingoptions->context = $context;
+ $ratingoptions->component = 'mod_data';
$ratingoptions->items = $records;
$ratingoptions->aggregate = $data->assessed;//the aggregation method
$ratingoptions->scaleid = $data->scale;
$ratingoptions->userid = $USER->id;
$ratingoptions->returnurl = $CFG->wwwroot.'/mod/data/'.$baseurl;
$ratingoptions->assesstimestart = $data->assesstimestart;
$ratingoptions->assesstimefinish = $data->assesstimefinish;
- $ratingoptions->plugintype = 'mod';
- $ratingoptions->pluginname = 'data';
$rm = new rating_manager();
$records = $rm->get_ratings($ratingoptions);
View
95 mod/forum/lib.php
@@ -3457,11 +3457,93 @@ function forum_rating_permissions($contextid) {
}
/**
- * Returns the names of the table and columns necessary to check items for ratings
- * @return array an array containing the item table, item id and user id columns
- */
-function forum_rating_item_check_info() {
- return array('forum_posts','id','userid');
+ * Validates a submitted rating
+ * @param array $params submitted data
+ * context => object the context in which the rated items exists [required]
+ * itemid => int the ID of the object being rated [required]
+ * scaleid => int the scale from which the user can select a rating. Used for bounds checking. [required]
+ * rating => int the submitted rating [required]
+ * rateduserid => int the id of the user whose items have been rated. NOT the user who submitted the ratings. 0 to update all. [required]
+ * aggregation => int the aggregation method to apply when calculating grades ie RATING_AGGREGATE_AVERAGE [required]
+ * @return boolean true if the rating is valid
+ */
+function forum_rating_add($params) {
+ global $DB, $USER;
+
+ if (!array_key_exists('itemid', $params) || !array_key_exists('context', $params)) {
+ return false;
+ }
+
+ $forumsql = "SELECT f.id as fid, f.course, d.id as did, p.userid as userid, p.created, f.assesstimestart, f.assesstimefinish, d.groupid
+ FROM {forum_posts} p
+ JOIN {forum_discussions} d ON p.discussion = d.id
+ JOIN {forum} f ON d.forum = f.id
+ WHERE p.id = :itemid";
+ $forumparams = array('itemid'=>$params['itemid']);
+ if (!$info = $DB->get_record_sql($forumsql, $forumparams)) {
+ //item id doesn't exist
+ return false;
+ }
+
+ if ($info->userid == $USER->id) {
+ //user is attempting to rate their own post
+ return false;
+ }
+
+ //check the item we're rating was created in the assessable time window
+ if (!empty($info->assesstimestart) && !empty($info->assesstimefinish)) {
+ if ($info->timecreated < $info->assesstimestart || $info->timecreated > $info->assesstimefinish) {
+ return false;
+ }
+ }
+
+ $forumid = $info->fid;
+ $discussionid = $info->did;
+ $groupid = $info->groupid;
+ $courseid = $info->course;
+
+ $cm = get_coursemodule_from_instance('forum', $forumid);
+ if (empty($cm)) {
+ return false;
+ }
+ $context = get_context_instance(CONTEXT_MODULE, $cm->id);
+
+ //if the supplied context doesnt match the item's context
+ if (empty($context) || $context->id != $params['context']->id) {
+ return false;
+ }
+
+ // Make sure groups allow this user to see the item they're rating
+ $course = $DB->get_record('course', array('id'=>$courseid), '*', MUST_EXIST);
+ if ($groupid > 0 and $groupmode = groups_get_activity_groupmode($cm, $course)) { // Groups are being used
+ if (!groups_group_exists($groupid)) { // Can't find group
+ return false;//something is wrong
+ }
+
+ if (!groups_is_member($groupid) and !has_capability('moodle/site:accessallgroups', $context)) {
+ // do not allow rating of posts from other groups when in SEPARATEGROUPS or VISIBLEGROUPS
+ return false;
+ }
+ }
+
+ //need to load the full objects here as ajax scripts don't like
+ //the debugging messages produced by forum_user_can_see_post() if you just supply IDs
+ if (!$forum = $DB->get_record('forum',array('id'=>$forumid))) {
+ return false;
+ }
+ if (!$post = $DB->get_record('forum_posts',array('id'=>$params['itemid']))) {
+ return false;
+ }
+ if (!$discussion = $DB->get_record('forum_discussions',array('id'=>$discussionid))) {
+ return false;
+ }
+
+ //perform some final capability checks
+ if( !forum_user_can_see_post($forum, $discussion, $post, $USER, $cm)) {
+ return false;
+ }
+
+ return true;
}
@@ -5333,6 +5415,7 @@ function forum_print_discussion($course, $cm, $forum, $discussion, $post, $mode,
if ($forum->assessed!=RATING_AGGREGATE_NONE) {
$ratingoptions = new stdclass();
$ratingoptions->context = $modcontext;
+ $ratingoptions->component = 'mod_forum';
$ratingoptions->items = $posts;
$ratingoptions->aggregate = $forum->assessed;//the aggregation method
$ratingoptions->scaleid = $forum->scale;
@@ -5344,8 +5427,6 @@ function forum_print_discussion($course, $cm, $forum, $discussion, $post, $mode,
}
$ratingoptions->assesstimestart = $forum->assesstimestart;
$ratingoptions->assesstimefinish = $forum->assesstimefinish;
- $ratingoptions->plugintype = 'mod';
- $ratingoptions->pluginname = 'forum';
$rm = new rating_manager();
$posts = $rm->get_ratings($ratingoptions);
View
1 mod/forum/user.php
@@ -165,6 +165,7 @@
//load ratings
if ($forum->assessed!=RATING_AGGREGATE_NONE) {
$ratingoptions->context = $forum->context;
+ $ratingoptions->component = 'mod_forum';
$ratingoptions->items = array($post);
$ratingoptions->aggregate = $forum->assessed;//the aggregation method
$ratingoptions->scaleid = $forum->scale;
View
63 mod/glossary/lib.php
@@ -471,11 +471,64 @@ function glossary_rating_permissions($options) {
}
/**
- * Returns the names of the table and columns necessary to check items for ratings
- * @return array an array containing the item table, item id and user id columns
- */
-function glossary_rating_item_check_info() {
- return array('glossary_entries','id','userid');
+ * Validates a submitted rating
+ * @param array $params submitted data
+ * context => object the context in which the rated items exists [required]
+ * itemid => int the ID of the object being rated
+ * scaleid => int the scale from which the user can select a rating. Used for bounds checking. [required]
+ * rating => int the submitted rating
+ * rateduserid => int the id of the user whose items have been rated. NOT the user who submitted the ratings. 0 to update all. [required]
+ * aggregation => int the aggregation method to apply when calculating grades ie RATING_AGGREGATE_AVERAGE [optional]
+ * @return boolean true if the rating is valid
+ */
+function glossary_rating_add($params) {
+ global $DB, $USER;
+
+ if (!array_key_exists('itemid', $params) || !array_key_exists('context', $params)) {
+ return false;
+ }
+
+ $glossarysql = "SELECT g.id as gid, e.userid as userid, e.approved, e.timecreated, g.assesstimestart, g.assesstimefinish
+ FROM {glossary_entries} e
+ JOIN {glossary} g ON e.glossaryid = g.id
+ WHERE e.id = :itemid";
+ $glossaryparams = array('itemid'=>$params['itemid']);
+ if (!$info = $DB->get_record_sql($glossarysql, $glossaryparams)) {
+ //item id doesn't exist
+ return false;
+ }
+
+ if ($info->userid == $USER->id) {
+ //user is attempting to rate their own glossary entry
+ return false;
+ }
+
+ if (!$info->approved) {
+ //item isnt approved
+ return false;
+ }
+
+ //check the item we're rating was created in the assessable time window
+ if (!empty($info->assesstimestart) && !empty($info->assesstimefinish)) {
+ if ($info->timecreated < $info->assesstimestart || $info->timecreated > $info->assesstimefinish) {
+ return false;
+ }
+ }
+
+ $glossaryid = $info->gid;
+
+ $cm = get_coursemodule_from_instance('glossary', $glossaryid);
+ if (empty($cm)) {
+ return false;
+ }
+ $context = get_context_instance(CONTEXT_MODULE, $cm->id);
+
+ //if the supplied context doesnt match the item's context
+ if (empty($context) || $context->id != $params['context']->id) {
+ return false;
+ }
+
+ return true;
}
/**
View
3 mod/glossary/view.php
@@ -396,15 +396,14 @@
if ($glossary->assessed!=RATING_AGGREGATE_NONE) {
$ratingoptions = new stdclass();
$ratingoptions->context = $context;
+ $ratingoptions->component = 'mod_glossary';
$ratingoptions->items = $allentries;
$ratingoptions->aggregate = $glossary->assessed;//the aggregation method
$ratingoptions->scaleid = $glossary->scale;
$ratingoptions->userid = $USER->id;
$ratingoptions->returnurl = $CFG->wwwroot.'/mod/glossary/view.php?id='.$cm->id;
$ratingoptions->assesstimestart = $glossary->assesstimestart;
$ratingoptions->assesstimefinish = $glossary->assesstimefinish;
- $ratingoptions->plugintype = 'mod';
- $ratingoptions->pluginname = 'glossary';
$rm = new rating_manager();
$allentries = $rm->get_ratings($ratingoptions);
View
68 rating/lib.php
@@ -51,6 +51,12 @@ class rating implements renderable {
public $context;
/**
+ * The component using ratings. For example "mod_forum"
+ * @var component
+ */
+ public $component;
+
+ /**
* The id of the item (forum post, glossary item etc) being rated
* @var int
*/
@@ -78,13 +84,15 @@ class rating implements renderable {
* Constructor.
* @param object $options {
* context => context context to use for the rating [required]
+ * component => component using ratings ie mod_forum [required]
* itemid => int the id of the associated item (forum post, glossary item etc) [required]
* scaleid => int The scale in use when the rating was submitted [required]
* userid => int The id of the user who submitted the rating [required]
* }
*/
public function __construct($options) {
$this->context = $options->context;
+ $this->component = $options->component;
$this->itemid = $options->itemid;
$this->scaleid = $options->scaleid;
$this->userid = $options->userid;
@@ -107,6 +115,7 @@ public function update_rating($rating) {
$ratingoptions = new stdclass();
$ratingoptions->context = $this->context;
+ $ratingoptions->component = $this->component;
$ratingoptions->items = $items;
$ratingoptions->aggregate = RATING_AGGREGATE_AVERAGE;//we dont actually care what aggregation method is applied
$ratingoptions->scaleid = $this->scaleid;
@@ -236,15 +245,14 @@ public function get_all_ratings_for_item($options) {
* Rating objects are available at $item->rating
* @param object $options {
* context => context the context in which the ratings exists [required]
+ * component => the component name ie mod_forum [required]
* items => array an array of items such as forum posts or glossary items. They must have an 'id' member ie $items[0]->id[required]
* aggregate => int what aggregation method should be applied. RATING_AGGREGATE_AVERAGE, RATING_AGGREGATE_MAXIMUM etc [required]
* 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]
- * plugintype => string plugin type ie 'mod' Used to find the permissions callback [optional]
- * pluginname => string plugin name ie 'forum' Used to find the permissions callback [optional]
* @return array the array of items with their ratings attached at $items[0]->rating
*/
public function get_ratings($options) {
@@ -335,6 +343,7 @@ public function get_ratings($options) {
//should $settings and $settings->permissions be declared as proper classes?
$settings = new stdclass(); //settings that are common to all ratings objects in this context
+ $settings->component =$options->component;
$settings->scale = $scaleobj; //the scale to use now
$settings->aggregationmethod = $options->aggregate;
if( !empty($options->returnurl) ) {
@@ -357,9 +366,7 @@ public function get_ratings($options) {
$settings->permissions->rate = has_capability('moodle/rating:rate',$options->context);//can submit ratings
//check module capabilities (mostly for backwards compatability with old modules that previously implemented their own ratings)
- $plugintype = !empty($options->plugintype) ? $options->plugintype : null;
- $pluginname = !empty($options->pluginname) ? $options->pluginname : null;
- $pluginpermissionsarray = $this->get_plugin_permissions_array($options->context->id, $plugintype, $pluginname);
+ $pluginpermissionsarray = $this->get_plugin_permissions_array($options->context->id, $options->component);
$settings->pluginpermissions = new stdclass();
$settings->pluginpermissions->view = $pluginpermissionsarray['view'];
@@ -370,6 +377,7 @@ public function get_ratings($options) {
$rating = null;
$ratingoptions = new stdclass();
$ratingoptions->context = $options->context;//context is common to all ratings in the set
+ $ratingoptions->component = $options->component;
foreach($options->items as $item) {
$rating = null;
//match the item with its corresponding rating
@@ -601,43 +609,45 @@ public function get_aggregation_method($aggregate) {
/**
* Looks for a callback and retrieves permissions from the plugin whose items are being rated
* @param int $contextid The current context id
- * @param string plugintype the type of plugin ie 'mod'
- * @param string pluginname the name of the plugin ie 'forum'
+ * @param string component the name of the component that is using ratings ie 'mod_forum'
* @return array rating related permissions
*/
- public function get_plugin_permissions_array($contextid, $plugintype=null, $pluginname=null) {
+ public function get_plugin_permissions_array($contextid, $component=null) {
$pluginpermissionsarray = null;
$defaultpluginpermissions = array('rate'=>true,'view'=>true,'viewany'=>true,'viewall'=>true);//all true == rely on system level permissions if no plugin callback is defined
- if ($plugintype && $pluginname) {
- $pluginpermissionsarray = plugin_callback($plugintype, $pluginname, 'rating', 'permissions', array($contextid), $defaultpluginpermissions);
+ if (!empty($component)) {
+ list($type, $name) = normalize_component($component);
+ $pluginpermissionsarray = plugin_callback($type, $name, 'rating', 'permissions', array($contextid), $defaultpluginpermissions);
} else {
$pluginpermissionsarray = $defaultpluginpermissions;
}
return $pluginpermissionsarray;
}
/**
- * Checks if the item exists and is NOT owned by the current owner. Uses a callback to find out what table to look in.
- * @param string plugintype the type of plugin ie 'mod'
- * @param string pluginname the name of the plugin ie 'forum'
- * @return boolean True if the callback doesn't exist. True if the item exists and doesn't belong to the current user. False otherwise.
- */
- public function check_item_and_owner($plugintype, $pluginname, $itemid) {
- global $DB, $USER;
-
- list($tablename,$itemidcol,$useridcol) = plugin_callback($plugintype, $pluginname, 'rating', 'item_check_info');
+ * Validates a submitted rating
+ * @param array $params submitted data
+ * context => object the context in which the rated items exists [required]
+ * itemid => int the ID of the object being rated
+ * scaleid => int the scale from which the user can select a rating. Used for bounds checking. [required]
+ * rating => int the submitted rating
+ * rateduserid => int the id of the user whose items have been rated. NOT the user who submitted the ratings. 0 to update all. [required]
+ * aggregation => int the aggregation method to apply when calculating grades ie RATING_AGGREGATE_AVERAGE [optional]
+ * @return boolean true if the rating is valid
+ */
+ public function check_rating_is_valid($component, $params) {
+ list($plugintype, $pluginname) = normalize_component($component);
- if (!empty($tablename)) {
- $item = $DB->get_record($tablename, array($itemidcol=>$itemid), $useridcol);
- if ($item) {
- if ($item->userid!=$USER->id) {
- return true;
- }
- }
+ //this looks for a function like forum_rating_is_valid() in mod_forum lib.php
+ //wrapping the params array in another array as call_user_func_array() expands arrays into multiple arguments
+ $isvalid = plugin_callback($plugintype, $pluginname, 'rating', 'add', array($params), null);
- return false;//item doesn't exist or belongs to the current user
- } else {
- return true;//callback doesn't exist
+ //if null then the callback doesn't exist
+ if ($isvalid === null) {
+ $isvalid = false;
+ debugging('plugin rating_add() function not found');
}
+
+ return $isvalid;
}
}//end rating_manager class definition
View
45 rating/rate.php
@@ -30,6 +30,7 @@
require_once('lib.php');
$contextid = required_param('contextid', PARAM_INT);
+$component = required_param('component', PARAM_ALPHAEXT);
$itemid = required_param('itemid', PARAM_INT);
$scaleid = required_param('scaleid', PARAM_INT);
$userrating = required_param('rating', PARAM_INT);
@@ -42,8 +43,10 @@
require_login($course, false, $cm);
$contextid = null;//now we have a context object throw away the id from the user
+$PAGE->set_context($context);
+$PAGE->set_url('/rating/rate.php', array('contextid'=>$context->id));
-if (!confirm_sesskey() || $USER->id==$rateduserid) {
+if (!confirm_sesskey() || $USER->id==$rateduserid || !has_capability('moodle/rating:rate',$context)) {
echo $OUTPUT->header();
echo get_string('ratepermissiondenied', 'rating');
echo $OUTPUT->footer();
@@ -53,32 +56,33 @@
$rm = new rating_manager();
//check the module rating permissions
-$pluginrateallowed = true;
-$pluginpermissionsarray = null;
-if ($context->contextlevel==CONTEXT_MODULE) {
- $plugintype = 'mod';
- $pluginname = $cm->modname;
- $pluginpermissionsarray = $rm->get_plugin_permissions_array($context->id, $plugintype, $pluginname);
- $pluginrateallowed = $pluginpermissionsarray['rate'];
-
- if ($pluginrateallowed) {
- //check the item exists and isn't owned by the current user
- $pluginrateallowed = $rm->check_item_and_owner($plugintype, $pluginname, $itemid);
- }
-}
+//doing this check here rather than within rating_manager::get_ratings() so we can return a json error response
+$pluginpermissionsarray = $rm->get_plugin_permissions_array($context->id, $component);
-if (!$pluginrateallowed || !has_capability('moodle/rating:rate',$context)) {
- echo $OUTPUT->header();
- echo get_string('ratepermissiondenied', 'rating');
- echo $OUTPUT->footer();
+if (!$pluginpermissionsarray['rate']) {
+ $result->error = get_string('ratepermissiondenied', 'rating');
+ echo json_encode($result);
die();
+} else {
+ $params = array(
+ 'context' => $context,
+ 'itemid' => $itemid,
+ 'scaleid' => $scaleid,
+ 'rating' => $userrating,
+ 'rateduserid' => $rateduserid);
+
+ if (!$rm->check_rating_is_valid($component, $params)) {
+ echo $OUTPUT->header();
+ echo get_string('ratinginvalid', 'rating');
+ echo $OUTPUT->footer();
+ die();
+ }
}
-$PAGE->set_url('/lib/rate.php', array('contextid'=>$context->id));
-
if ($userrating != RATING_UNSET_RATING) {
$ratingoptions = new stdClass();
$ratingoptions->context = $context;
+ $ratingoptions->component = $component;
$ratingoptions->itemid = $itemid;
$ratingoptions->scaleid = $scaleid;
$ratingoptions->userid = $USER->id;
@@ -88,6 +92,7 @@
} else { //delete the rating if the user set to Rate...
$options = new stdClass();
$options->contextid = $context->id;
+ $options->component = $component;
$options->userid = $USER->id;
$options->itemid = $itemid;
View
41 rating/rate_ajax.php
@@ -32,6 +32,7 @@
require_once('lib.php');
$contextid = required_param('contextid', PARAM_INT);
+$component = required_param('component', PARAM_ALPHAEXT);
$itemid = required_param('itemid', PARAM_INT);
$scaleid = required_param('scaleid', PARAM_INT);
$userrating = required_param('rating', PARAM_INT);
@@ -51,8 +52,10 @@
require_login($course, false, $cm);
$contextid = null;//now we have a context object throw away the id from the user
+$PAGE->set_context($context);
+$PAGE->set_url('/rating/rate_ajax.php', array('contextid'=>$context->id));
-if (!confirm_sesskey() || $USER->id==$rateduserid) {
+if (!confirm_sesskey() || $USER->id==$rateduserid || !has_capability('moodle/rating:rate',$context)) {
echo $OUTPUT->header();
echo get_string('ratepermissiondenied', 'rating');
echo $OUTPUT->footer();
@@ -62,32 +65,33 @@
$rm = new rating_manager();
//check the module rating permissions
-//doing this check here rather than within rating_manager::get_ratings so we can return a json error response
-$pluginrateallowed = true;
-$pluginpermissionsarray = null;
-if ($context->contextlevel==CONTEXT_MODULE) {
- $plugintype = 'mod';
- $pluginname = $cm->modname;
- $pluginpermissionsarray = $rm->get_plugin_permissions_array($context->id, $plugintype, $pluginname);
- $pluginrateallowed = $pluginpermissionsarray['rate'];
-
- if ($pluginrateallowed) {
- //check the item exists and isn't owned by the current user
- $pluginrateallowed = $rm->check_item_and_owner($plugintype, $pluginname, $itemid);
- }
-}
+//doing this check here rather than within rating_manager::get_ratings() so we can return a json error response
+$pluginpermissionsarray = $rm->get_plugin_permissions_array($context->id, $component);
-if (!$pluginrateallowed || !has_capability('moodle/rating:rate',$context)) {
+if (!$pluginpermissionsarray['rate']) {
$result->error = get_string('ratepermissiondenied', 'rating');
echo json_encode($result);
die();
+} else {
+ $params = array(
+ 'context' => $context,
+ 'itemid' => $itemid,
+ 'scaleid' => $scaleid,
+ 'rating' => $userrating,
+ 'rateduserid' => $rateduserid,
+ 'aggregation' => $aggregationmethod);
+
+ if (!$rm->check_rating_is_valid($component, $params)) {
+ $result->error = get_string('ratinginvalid', 'rating');
+ echo json_encode($result);
+ die();
+ }
}
-$PAGE->set_url('/lib/rate.php', array('contextid'=>$context->id));
-
//rating options used to update the rating then retrieve the aggregate
$ratingoptions = new stdClass();
$ratingoptions->context = $context;
+$ratingoptions->component = $component;
$ratingoptions->itemid = $itemid;
$ratingoptions->scaleid = $scaleid;
$ratingoptions->userid = $USER->id;
@@ -98,6 +102,7 @@
} else { //delete the rating if the user set to Rate...
$options = new stdClass();
$options->contextid = $context->id;
+ $options->component = $component;
$options->userid = $USER->id;
$options->itemid = $itemid;

0 comments on commit 4af7c9d

Please sign in to comment.
Something went wrong with that request. Please try again.