echo $OUTPUT->header(); echo get_string('ratinginvalid', 'rating'); echo $OUTPUT->footer(); die; } } if ($userrating != RATING_UNSET_RATING) { $ratingoptions = new stdClass(); $ratingoptions->context = $context; $ratingoptions->component = $component; $ratingoptions->ratingarea = $ratingarea; $ratingoptions->itemid = $itemid; $ratingoptions->scaleid = $scaleid; $ratingoptions->userid = $USER->id; $rating = new rating($ratingoptions); $rating->update_rating($userrating); } else { //delete the rating if the user set to Rate... $options = new stdClass(); $options->contextid = $context->id; $options->component = $component; $options->ratingarea = $ratingarea; $options->userid = $USER->id; $options->itemid = $itemid; $rm->delete_ratings($options); } //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 (!empty($cm) && $context->contextlevel == CONTEXT_MODULE) { //tell the module that its grades have changed $modinstance = $DB->get_record($cm->modname, array('id' => $cm->instance), '*', MUST_EXIST);
public function test_rating() { global $USER, $DB; $this->resetAfterTest(); $generator = $this->getDataGenerator()->get_plugin_generator('mod_forumng'); $course = $this->get_new_course(); $course2 = $this->get_new_course(); $suser = $this->get_new_user('student', $course->id); $this->setAdminUser(); $forum = $this->get_new_forumng($course->id, array('name' => 'TEST', 'intro' => 'abc123', 'enableratings' => mod_forumng::FORUMNG_STANDARD_RATING, 'ratingscale' => 10)); $forum2 = $this->get_new_forumng($course->id, array('name' => 'TEST2', 'intro' => 'abc123', 'enableratings' => mod_forumng::FORUMNG_NO_RATING)); $forum3 = $this->get_new_forumng($course2->id, array('name' => 'TEST', 'intro' => 'abc123', 'enableratings' => mod_forumng::FORUMNG_STANDARD_RATING, 'ratingscale' => 10)); $did1 = $generator->create_discussion(array('course' => $course, 'forum' => $forum->get_id(), 'userid' => $suser->id)); $did2 = $generator->create_discussion(array('course' => $course, 'forum' => $forum->get_id(), 'userid' => $suser->id)); $did3 = $generator->create_discussion(array('course' => $course, 'forum' => $forum->get_id(), 'userid' => $suser->id)); $did4 = $generator->create_discussion(array('course' => $course, 'forum' => $forum->get_id(), 'userid' => $suser->id)); // Add rating to all 3 discussions. $rm = new rating_manager(); $params = new stdClass(); $params->context = $forum->get_context(); $params->component = 'mod_forumng'; $params->ratingarea = 'post'; $params->scaleid = $forum->get_rating_scale(); $params->userid = $USER->id; $params->itemid = $did1[1]; $rating = new rating($params); $rating->update_rating(5); $params->itemid = $did2[1]; $rating = new rating($params); $rating->update_rating(5); $params->itemid = $did3[1]; $rating = new rating($params); $rating->update_rating(5); // Check rating object gets added where expected. $post = mod_forumng_post::get_from_id($did1[1], mod_forumng::CLONE_DIRECT, false, false); $ratings = $post->get_ratings(); $this->assertNotNull($ratings); $this->assertEquals($did1[1], $ratings->itemid); $post = mod_forumng_post::get_from_id($did1[1], mod_forumng::CLONE_DIRECT, true, false); $ratings = $post->get_ratings(); $this->assertNotNull($ratings); $this->assertEquals($did1[1], $ratings->itemid); $post = mod_forumng_post::get_from_id($did1[1], mod_forumng::CLONE_DIRECT, true, true); $ratings = $post->get_ratings(); $this->assertNotNull($ratings); $this->assertEquals($did1[1], $ratings->itemid); $ratedposts = $forum->get_all_posts_by_user($suser->id, null, 'fp.id', null, null, true); $this->assertCount(3, $ratedposts); $allposts = $forum->get_all_posts_by_user($suser->id, null); $this->assertCount(4, $allposts); $this->assertNotNull($allposts[$did1[1]]->get_ratings()); // Update grades (does nothing). $forum->update_grades(); // Enable rating grading, forumng_update_instance() should update grades. forumng_update_instance((object) array('instance' => $forum->get_id(), 'grading' => mod_forumng::GRADING_SUM)); $grades = grade_get_grades($course->id, 'mod', 'forumng', $forum->get_id(), $suser->id); // Note sum is set to 10 not 15 as max grade is 10. $this->assertEquals(10, abs($grades->items[0]->grades[$suser->id]->grade)); // Enable rating grading, forumng_update_instance() should update grades. forumng_update_instance((object) array('instance' => $forum->get_id(), 'grading' => mod_forumng::GRADING_COUNT)); $grades = grade_get_grades($course->id, 'mod', 'forumng', $forum->get_id(), $suser->id); $this->assertEquals(3, abs($grades->items[0]->grades[$suser->id]->grade)); // Check get_rated_posts_by_user. $extrapost = $generator->create_post(array('discussionid' => $did1[0], 'parentpostid' => $did1[1], 'userid' => $suser->id, 'created' => 1388589745)); $extraposts = $forum->get_rated_posts_by_user($forum, $suser->id, -1, 'fp.id', null, null); $this->assertCount(0, $extraposts); $extraposts = $forum->get_rated_posts_by_user($forum, $USER->id, -1, 'fp.id', null, null); $this->assertCount(3, $extraposts); $params->itemid = $extrapost->id; $rating = new rating($params); $rating->update_rating(10); $extraposts = $forum->get_rated_posts_by_user($forum, $USER->id, -1, 'fp.id', null, null); $this->assertCount(4, $extraposts); // Now filter out the 'old' extrapost. $extraposts = $forum->get_rated_posts_by_user($forum, $USER->id, -1, 'fp.id', null, null, 1388600000); $this->assertCount(3, $extraposts); // Check discussion delete. $discuss = mod_forumng_discussion::get_from_id($did1[0], mod_forumng::CLONE_DIRECT); $discuss->permanently_delete(); $rating = $DB->get_record('rating', array('itemid' => $did1[1])); $this->assertFalse($rating); $grades = grade_get_grades($course->id, 'mod', 'forumng', $forum->get_id(), $suser->id); $this->assertEquals(2, abs($grades->items[0]->grades[$suser->id]->grade)); // Check discussion move. $discuss = mod_forumng_discussion::get_from_id($did2[0], mod_forumng::CLONE_DIRECT); $discuss->move($forum2, 0); $grades = grade_get_grades($course->id, 'mod', 'forumng', $forum->get_id(), $suser->id); $this->assertEquals(1, abs($grades->items[0]->grades[$suser->id]->grade)); forumng_update_instance((object) array('instance' => $forum2->get_id(), 'grading' => mod_forumng::GRADING_COUNT, 'enableratings' => mod_forumng::FORUMNG_STANDARD_RATING, 'ratingscale' => 10)); $grades = grade_get_grades($course->id, 'mod', 'forumng', $forum2->get_id(), $suser->id); $this->assertEquals(1, abs($grades->items[0]->grades[$suser->id]->grade)); $rating = $DB->get_record('rating', array('itemid' => $did2[1])); $this->assertNotEmpty($rating); $this->assertEquals($forum2->get_context(true)->id, $rating->contextid); // Check discussion copy. $discuss = mod_forumng_discussion::get_from_id($did3[0], mod_forumng::CLONE_DIRECT); $discuss->copy($forum3, 0); $grades = grade_get_grades($course->id, 'mod', 'forumng', $forum->get_id(), $suser->id); $this->assertEquals(1, abs($grades->items[0]->grades[$suser->id]->grade)); // Check rating didn't copy as forum in another course. $ratingtotal = $DB->get_records('rating'); $this->assertCount(2, $ratingtotal); // Check rating does copy to foum in same course. $discuss->copy($forum2, 0); $ratingtotal = $DB->get_records('rating'); $this->assertCount(3, $ratingtotal); // Check forum deleting. course_delete_module($forum->get_course_module_id()); $ratingtotal = $DB->get_records('rating'); $this->assertCount(2, $ratingtotal); $grades = grade_get_grades($course->id, 'mod', 'forumng', $forum->get_id(), $suser->id); $this->assertEmpty($grades->items); }
/** * Tests for mod_forum_rating_can_see_item_ratings(). * * @throws coding_exception * @throws rating_exception */ public function test_mod_forum_rating_can_see_item_ratings() { global $DB; $this->resetAfterTest(); // Setup test data. $course = new stdClass(); $course->groupmode = SEPARATEGROUPS; $course->groupmodeforce = true; $course = $this->getDataGenerator()->create_course($course); $forum = $this->getDataGenerator()->create_module('forum', array('course' => $course->id)); $generator = self::getDataGenerator()->get_plugin_generator('mod_forum'); $cm = get_coursemodule_from_instance('forum', $forum->id); $context = context_module::instance($cm->id); // Create users. $user1 = $this->getDataGenerator()->create_user(); $user2 = $this->getDataGenerator()->create_user(); $user3 = $this->getDataGenerator()->create_user(); $user4 = $this->getDataGenerator()->create_user(); // Groups and stuff. $role = $DB->get_record('role', array('shortname' => 'teacher'), '*', MUST_EXIST); $this->getDataGenerator()->enrol_user($user1->id, $course->id, $role->id); $this->getDataGenerator()->enrol_user($user2->id, $course->id, $role->id); $this->getDataGenerator()->enrol_user($user3->id, $course->id, $role->id); $this->getDataGenerator()->enrol_user($user4->id, $course->id, $role->id); $group1 = $this->getDataGenerator()->create_group(array('courseid' => $course->id)); $group2 = $this->getDataGenerator()->create_group(array('courseid' => $course->id)); groups_add_member($group1, $user1); groups_add_member($group1, $user2); groups_add_member($group2, $user3); groups_add_member($group2, $user4); $record = new stdClass(); $record->course = $forum->course; $record->forum = $forum->id; $record->userid = $user1->id; $record->groupid = $group1->id; $discussion = $generator->create_discussion($record); // Retrieve the first post. $post = $DB->get_record('forum_posts', array('discussion' => $discussion->id)); $ratingoptions = new stdClass(); $ratingoptions->context = $context; $ratingoptions->ratingarea = 'post'; $ratingoptions->component = 'mod_forum'; $ratingoptions->itemid = $post->id; $ratingoptions->scaleid = 2; $ratingoptions->userid = $user2->id; $rating = new rating($ratingoptions); $rating->update_rating(2); // Now try to access it as various users. unassign_capability('moodle/site:accessallgroups', $role->id); $params = array('contextid' => 2, 'component' => 'mod_forum', 'ratingarea' => 'post', 'itemid' => $post->id, 'scaleid' => 2); $this->setUser($user1); $this->assertTrue(mod_forum_rating_can_see_item_ratings($params)); $this->setUser($user2); $this->assertTrue(mod_forum_rating_can_see_item_ratings($params)); $this->setUser($user3); $this->assertFalse(mod_forum_rating_can_see_item_ratings($params)); $this->setUser($user4); $this->assertFalse(mod_forum_rating_can_see_item_ratings($params)); // Now try with accessallgroups cap and make sure everything is visible. assign_capability('moodle/site:accessallgroups', CAP_ALLOW, $role->id, $context->id); $this->setUser($user1); $this->assertTrue(mod_forum_rating_can_see_item_ratings($params)); $this->setUser($user2); $this->assertTrue(mod_forum_rating_can_see_item_ratings($params)); $this->setUser($user3); $this->assertTrue(mod_forum_rating_can_see_item_ratings($params)); $this->setUser($user4); $this->assertTrue(mod_forum_rating_can_see_item_ratings($params)); // Change group mode and verify visibility. $course->groupmode = VISIBLEGROUPS; $DB->update_record('course', $course); unassign_capability('moodle/site:accessallgroups', $role->id); $this->setUser($user1); $this->assertTrue(mod_forum_rating_can_see_item_ratings($params)); $this->setUser($user2); $this->assertTrue(mod_forum_rating_can_see_item_ratings($params)); $this->setUser($user3); $this->assertTrue(mod_forum_rating_can_see_item_ratings($params)); $this->setUser($user4); $this->assertTrue(mod_forum_rating_can_see_item_ratings($params)); }
/** * Adds a new rating * * @param stdClass $cm course module object * @param stdClass $context context object * @param string $component component name * @param string $ratingarea rating area * @param int $itemid the item id * @param int $scaleid the scale id * @param int $userrating the user rating * @param int $rateduserid the rated user id * @param int $aggregationmethod the aggregation method * @since Moodle 3.2 */ public function add_rating($cm, $context, $component, $ratingarea, $itemid, $scaleid, $userrating, $rateduserid, $aggregationmethod) { global $CFG, $DB, $USER; $result = new stdClass(); // Check the module rating permissions. // Doing this check here rather than within rating_manager::get_ratings() so we can return a error response. $pluginpermissionsarray = $this->get_plugin_permissions_array($context->id, $component, $ratingarea); if (!$pluginpermissionsarray['rate']) { $result->error = 'ratepermissiondenied'; return $result; } else { $params = array('context' => $context, 'component' => $component, 'ratingarea' => $ratingarea, 'itemid' => $itemid, 'scaleid' => $scaleid, 'rating' => $userrating, 'rateduserid' => $rateduserid, 'aggregation' => $aggregationmethod); if (!$this->check_rating_is_valid($params)) { $result->error = 'ratinginvalid'; return $result; } } // Rating options used to update the rating then retrieve the aggregate. $ratingoptions = new stdClass(); $ratingoptions->context = $context; $ratingoptions->ratingarea = $ratingarea; $ratingoptions->component = $component; $ratingoptions->itemid = $itemid; $ratingoptions->scaleid = $scaleid; $ratingoptions->userid = $USER->id; if ($userrating != RATING_UNSET_RATING) { $rating = new rating($ratingoptions); $rating->update_rating($userrating); } else { // Delete the rating if the user set to "Rate..." $options = new stdClass(); $options->contextid = $context->id; $options->component = $component; $options->ratingarea = $ratingarea; $options->userid = $USER->id; $options->itemid = $itemid; $this->delete_ratings($options); } // Future possible enhancement: add a setting to turn grade updating off for those who don't want them in gradebook. // Note that this would need to be done in both rate.php and rate_ajax.php. if ($context->contextlevel == CONTEXT_MODULE) { // Tell the module that its grades have changed. $modinstance = $DB->get_record($cm->modname, array('id' => $cm->instance)); if ($modinstance) { $modinstance->cmidnumber = $cm->id; // MDL-12961. $functionname = $cm->modname . '_update_grades'; require_once $CFG->dirroot . "/mod/{$cm->modname}/lib.php"; if (function_exists($functionname)) { $functionname($modinstance, $rateduserid); } } } // Object to return to client as JSON. $result->success = true; // Need to retrieve the updated item to get its new aggregate value. $item = new stdClass(); $item->id = $itemid; // Most of $ratingoptions variables were previously set. $ratingoptions->items = array($item); $ratingoptions->aggregate = $aggregationmethod; $items = $this->get_ratings($ratingoptions); $firstrating = $items[0]->rating; // See if the user has permission to see the rating aggregate. if ($firstrating->user_can_view_aggregate()) { // For custom scales return text not the value. // This scales weirdness will go away when scales are refactored. $scalearray = null; $aggregatetoreturn = round($firstrating->aggregate, 1); // Output a dash if aggregation method == COUNT as the count is output next to the aggregate anyway. if ($firstrating->settings->aggregationmethod == RATING_AGGREGATE_COUNT or $firstrating->count == 0) { $aggregatetoreturn = ' - '; } else { if ($firstrating->settings->scale->id < 0) { // If its non-numeric scale. // Dont use the scale item if the aggregation method is sum as adding items from a custom scale makes no sense. if ($firstrating->settings->aggregationmethod != RATING_AGGREGATE_SUM) { $scalerecord = $DB->get_record('scale', array('id' => -$firstrating->settings->scale->id)); if ($scalerecord) { $scalearray = explode(',', $scalerecord->scale); $aggregatetoreturn = $scalearray[$aggregatetoreturn - 1]; } } } } $result->aggregate = $aggregatetoreturn; $result->count = $firstrating->count; $result->itemid = $itemid; } return $result; }