Permalink
Browse files

Merge branch 'MDL-26838_ratings_bad_data3' of git://github.com/andyjd…

…avis/moodle into MOODLE_20_STABLE
  • Loading branch information...
2 parents 8351ce1 + 34b5e85 commit 1374c61bb423b86890fabd61e40f17e23ea0ce21 Sam Hemelryk committed May 5, 2011
Showing with 336 additions and 87 deletions.
  1. +1 −0 lang/en/rating.php
  2. +4 −0 lib/outputrenderers.php
  3. +77 −4 mod/data/lib.php
  4. +1 −2 mod/data/view.php
  5. +92 −6 mod/forum/lib.php
  6. +1 −0 mod/forum/user.php
  7. +62 −4 mod/glossary/lib.php
  8. +1 −2 mod/glossary/view.php
  9. +49 −31 rating/lib.php
  10. +25 −20 rating/rate.php
  11. +23 −18 rating/rate_ajax.php
View
@@ -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
@@ -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
@@ -1365,11 +1365,84 @@ 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. Will throw rating_exception if not
*/
-function data_rating_item_check_info() {
- return array('data_records','id','userid');
+function data_rating_validate($params) {
+ global $DB, $USER;
+
+ if (!array_key_exists('itemid', $params) || !array_key_exists('context', $params) || !array_key_exists('rateduserid', $params)) {
+ throw new rating_exception('missingparameter');
+ }
+
+ $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 doesn't exist
+ throw new rating_exception('invaliditemid');
+ }
+
+ if ($info->userid == $USER->id) {
+ //user is attempting to rate their own glossary entry
+ throw new rating_exception('nopermissiontorate');
+ }
+
+ if ($params['rateduserid'] != $info->userid) {
+ //supplied user ID doesnt match the user ID from the database
+ throw new rating_exception('invaliduserid');
+ }
+
+ if ($info->approval && !$info->approved) {
+ //database requires approval but this item isnt approved
+ throw new rating_exception('nopermissiontorate');
+ }
+
+ //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) {
+ throw new rating_exception('notavailable');
+ }
+ }
+
+ $dataid = $info->did;
+ $groupid = $info->groupid;
+ $courseid = $info->course;
+
+ $cm = get_coursemodule_from_instance('data', $dataid);
+ if (empty($cm)) {
+ throw new rating_exception('unknowncontext');
+ }
+ $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) {
+ throw new rating_exception('invalidcontext');
+ }
+
+ // 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
+ throw new rating_exception('cannotfindgroup');//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
+ throw new rating_exception('notmemberofgroup');
+ }
+ }
+
+ return true;
}
View
@@ -671,15 +671,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
@@ -3457,11 +3457,98 @@ 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
+ * 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. Will throw rating_exception if not
*/
-function forum_rating_item_check_info() {
- return array('forum_posts','id','userid');
+function forum_rating_validate($params) {
+ global $DB, $USER;
+
+ if (!array_key_exists('itemid', $params) || !array_key_exists('context', $params) || !array_key_exists('rateduserid', $params)) {
+ throw new rating_exception('missingparameter');
+ }
+
+ $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 doesn't exist
+ throw new rating_exception('invaliditemid');
+ }
+
+ if ($info->userid == $USER->id) {
+ //user is attempting to rate their own post
+ throw new rating_exception('nopermissiontorate');
+ }
+
+ if ($params['rateduserid'] != $info->userid) {
+ //supplied user ID doesnt match the user ID from the database
+ throw new rating_exception('invaliduserid');
+ }
+
+ //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) {
+ throw new rating_exception('notavailable');
+ }
+ }
+
+ $forumid = $info->fid;
+ $discussionid = $info->did;
+ $groupid = $info->groupid;
+ $courseid = $info->course;
+
+ $cm = get_coursemodule_from_instance('forum', $forumid);
+ if (empty($cm)) {
+ throw new rating_exception('unknowncontext');
+ }
+ $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) {
+ throw new rating_exception('invalidcontext');
+ }
+
+ // 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
+ throw new rating_exception('cannotfindgroup');//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
+ throw new rating_exception('notmemberofgroup');
+ }
+ }
+
+ //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))) {
+ throw new rating_exception('invalidrecordunknown');
+ }
+ if (!$post = $DB->get_record('forum_posts',array('id'=>$params['itemid']))) {
+ throw new rating_exception('invalidrecordunknown');
+ }
+ if (!$discussion = $DB->get_record('forum_discussions',array('id'=>$discussionid))) {
+ throw new rating_exception('invalidrecordunknown');
+ }
+
+ //perform some final capability checks
+ if( !forum_user_can_see_post($forum, $discussion, $post, $USER, $cm)) {
+ throw new rating_exception('nopermissiontorate');
+ }
+
+ return true;
}
@@ -5333,6 +5420,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 +5432,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
@@ -166,6 +166,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
@@ -471,11 +471,69 @@ 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
+ * 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. Will throw rating_exception if not
*/
-function glossary_rating_item_check_info() {
- return array('glossary_entries','id','userid');
+function glossary_rating_validate($params) {
+ global $DB, $USER;
+
+ if (!array_key_exists('itemid', $params) || !array_key_exists('context', $params) || !array_key_exists('rateduserid', $params)) {
+ throw new rating_exception('missingparameter');
+ }
+
+ $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 doesn't exist
+ throw new rating_exception('invaliditemid');
+ }
+
+ if ($info->userid == $USER->id) {
+ //user is attempting to rate their own glossary entry
+ throw new rating_exception('nopermissiontorate');
+ }
+
+ if ($params['rateduserid'] != $info->userid) {
+ //supplied user ID doesnt match the user ID from the database
+ throw new rating_exception('invaliduserid');
+ }
+
+ if (!$info->approved) {
+ //item isnt approved
+ throw new rating_exception('nopermissiontorate');
+ }
+
+ //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) {
+ throw new rating_exception('notavailable');
+ }
+ }
+
+ $glossaryid = $info->gid;
+
+ $cm = get_coursemodule_from_instance('glossary', $glossaryid);
+ if (empty($cm)) {
+ throw new rating_exception('unknowncontext');
+ }
+ $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) {
+ throw new rating_exception('invalidcontext');
+ }
+
+ return true;
}
/**
View
@@ -400,15 +400,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);
Oops, something went wrong.

0 comments on commit 1374c61

Please sign in to comment.