rating MDL-21657 added type to phpdocs and adjusted whitespace
This commit is contained in:
+245
-252
@@ -23,9 +23,9 @@
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
|
||||
define('RATING_VIEW','view');
|
||||
define('RATING_VIEW_ALL','viewall');
|
||||
define('RATING_POST','post');
|
||||
define('RATING_VIEW','view');
|
||||
define('RATING_VIEW_ALL','viewall');
|
||||
define('RATING_POST','post');
|
||||
|
||||
define('RATING_UNSET_RATING', -999);
|
||||
|
||||
@@ -44,269 +44,262 @@ define ('RATING_AGGREGATE_SUM', 5);
|
||||
* @since Moodle 2.0
|
||||
*/
|
||||
class rating implements renderable {
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
* @param $contextid the current context
|
||||
* @param $itemid the id of the associated item (forum post, glossary item etc)
|
||||
* @param $scaleid the scale to use
|
||||
* @param $userid the user submitting the rating
|
||||
*/
|
||||
function __construct($context, $itemid, $scaleid, $userid) {
|
||||
$this->context = $context;
|
||||
$this->itemid = $itemid;
|
||||
$this->scaleid = $scaleid;
|
||||
$this->userid = $userid;
|
||||
}
|
||||
|
||||
/**
|
||||
* Update this rating in the database
|
||||
* @param integer $rating the integer value of this rating
|
||||
*/
|
||||
function update_rating($rating) {
|
||||
global $DB;
|
||||
|
||||
$data = new stdclass();
|
||||
$table = 'rating';
|
||||
|
||||
$item = new stdclass();
|
||||
$item->id = $this->itemid;
|
||||
$items = array($item);
|
||||
|
||||
$items = rating::load_ratings($this->context, $items, null, $this->scaleid, $this->userid);
|
||||
if( !isset($items[0]->rating) || !isset($items[0]->rating->id) ) {
|
||||
$data->contextid = $this->context->id;
|
||||
$data->rating = $rating;
|
||||
$data->scaleid = $this->scaleid;
|
||||
$data->userid = $this->userid;
|
||||
$data->itemid = $this->itemid;
|
||||
|
||||
$time = time();
|
||||
$data->timecreated = $time;
|
||||
$data->timemodified = $time;
|
||||
|
||||
$DB->insert_record($table, $data);
|
||||
/**
|
||||
* Constructor.
|
||||
* @param int $contextid the current context
|
||||
* @param int $itemid the id of the associated item (forum post, glossary item etc)
|
||||
* @param int $scaleid the scale to use
|
||||
* @param int $userid the user submitting the rating
|
||||
*/
|
||||
public function __construct($context, $itemid, $scaleid, $userid) {
|
||||
$this->context = $context;
|
||||
$this->itemid = $itemid;
|
||||
$this->scaleid = $scaleid;
|
||||
$this->userid = $userid;
|
||||
}
|
||||
else {
|
||||
//$data->id = $this->id;
|
||||
$data->id = $items[0]->rating->id;
|
||||
/*$data->contextid = $this->context->id;
|
||||
$data->scaleid = $this->scaleid;
|
||||
$data->userid = $this->userid;*/
|
||||
$data->rating = $rating;
|
||||
|
||||
$time = time();
|
||||
$data->timemodified = $time;
|
||||
/**
|
||||
* Update this rating in the database
|
||||
* @param int $rating the integer value of this rating
|
||||
*/
|
||||
public function update_rating($rating) {
|
||||
global $DB;
|
||||
|
||||
$DB->update_record($table, $data);
|
||||
$data = new stdclass();
|
||||
$table = 'rating';
|
||||
|
||||
$item = new stdclass();
|
||||
$item->id = $this->itemid;
|
||||
$items = array($item);
|
||||
|
||||
$items = rating::load_ratings($this->context, $items, null, $this->scaleid, $this->userid);
|
||||
if( !isset($items[0]->rating) || !isset($items[0]->rating->id) ) {
|
||||
$data->contextid = $this->context->id;
|
||||
$data->rating = $rating;
|
||||
$data->scaleid = $this->scaleid;
|
||||
$data->userid = $this->userid;
|
||||
$data->itemid = $this->itemid;
|
||||
|
||||
$time = time();
|
||||
$data->timecreated = $time;
|
||||
$data->timemodified = $time;
|
||||
|
||||
$DB->insert_record($table, $data);
|
||||
}
|
||||
else {
|
||||
//$data->id = $this->id;
|
||||
$data->id = $items[0]->rating->id;
|
||||
/*$data->contextid = $this->context->id;
|
||||
$data->scaleid = $this->scaleid;
|
||||
$data->userid = $this->userid;*/
|
||||
$data->rating = $rating;
|
||||
|
||||
$time = time();
|
||||
$data->timemodified = $time;
|
||||
|
||||
$DB->update_record($table, $data);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Retreive the integer value of this rating
|
||||
*/
|
||||
function get_rating() {
|
||||
return $this->rating;
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove this rating from the database
|
||||
*/
|
||||
function delete_rating() {
|
||||
//todo implement this if its actually needed
|
||||
}
|
||||
|
||||
/**
|
||||
* Static method that converts an aggregation method constant into something that can be included in SQL
|
||||
* @param $aggregate An aggregation constant. For example, RATING_AGGREGATE_AVERAGE.
|
||||
*/
|
||||
public static function rating_get_aggregation_method($aggregate) {
|
||||
$aggregatestr = null;
|
||||
switch($aggregate){
|
||||
case RATING_AGGREGATE_AVERAGE:
|
||||
$aggregatestr = 'AVG';
|
||||
break;
|
||||
case RATING_AGGREGATE_COUNT:
|
||||
$aggregatestr = 'CNT';
|
||||
break;
|
||||
case RATING_AGGREGATE_MAXIMUM:
|
||||
$aggregatestr = 'MAX';
|
||||
break;
|
||||
case RATING_AGGREGATE_MINIMUM:
|
||||
$aggregatestr = 'MIN';
|
||||
break;
|
||||
case RATING_AGGREGATE_SUM:
|
||||
$aggregatestr = 'SUM';
|
||||
break;
|
||||
/**
|
||||
* Retreive the integer value of this rating
|
||||
* @return the integer value of this rating object
|
||||
*/
|
||||
public function get_rating() {
|
||||
return $this->rating;
|
||||
}
|
||||
return $aggregatestr;
|
||||
}
|
||||
|
||||
/**
|
||||
* Static method that returns an array of ratings for a given item (forum post, glossary entry etc)
|
||||
* This returns all users ratings for a single item
|
||||
* @param $context the context in which the rating exists
|
||||
* @param $itemid The id of the forum posts, glossary items or whatever
|
||||
*/
|
||||
public static function load_ratings_for_item($context, $itemid, $sort) {
|
||||
global $DB;
|
||||
/**
|
||||
* Remove this rating from the database
|
||||
*/
|
||||
public function delete_rating() {
|
||||
//todo implement this if its actually needed
|
||||
}
|
||||
|
||||
$sql = "SELECT r.id, r.rating, r.itemid, r.userid, r.timemodified,
|
||||
u.firstname, u.lastname, u.imagealt, u.picture
|
||||
FROM {rating} r
|
||||
LEFT JOIN {user} u ON r.userid = u.id
|
||||
WHERE
|
||||
r.contextid = :contextid AND
|
||||
r.itemid = :itemid
|
||||
$sort";
|
||||
/**
|
||||
* Static method that converts an aggregation method constant into something that can be included in SQL
|
||||
* @param $aggregate An aggregation constant. For example, RATING_AGGREGATE_AVERAGE.
|
||||
*/
|
||||
public static function rating_get_aggregation_method($aggregate) {
|
||||
$aggregatestr = null;
|
||||
switch($aggregate){
|
||||
case RATING_AGGREGATE_AVERAGE:
|
||||
$aggregatestr = 'AVG';
|
||||
break;
|
||||
case RATING_AGGREGATE_COUNT:
|
||||
$aggregatestr = 'CNT';
|
||||
break;
|
||||
case RATING_AGGREGATE_MAXIMUM:
|
||||
$aggregatestr = 'MAX';
|
||||
break;
|
||||
case RATING_AGGREGATE_MINIMUM:
|
||||
$aggregatestr = 'MIN';
|
||||
break;
|
||||
case RATING_AGGREGATE_SUM:
|
||||
$aggregatestr = 'SUM';
|
||||
break;
|
||||
}
|
||||
return $aggregatestr;
|
||||
}
|
||||
|
||||
$params['contextid'] = $context->id;
|
||||
$params['itemid'] = $itemid;
|
||||
/**
|
||||
* Static method that returns an array of ratings for a given item (forum post, glossary entry etc)
|
||||
* This returns all users ratings for a single item
|
||||
* @param context $context the context in which the rating exists
|
||||
* @param int $itemid The id of the forum posts, glossary items or whatever
|
||||
*/
|
||||
public static function load_ratings_for_item($context, $itemid, $sort) {
|
||||
global $DB;
|
||||
|
||||
return $DB->get_records_sql($sql, $params);
|
||||
}
|
||||
$sql = "SELECT r.id, r.rating, r.itemid, r.userid, r.timemodified,
|
||||
u.firstname, u.lastname, u.imagealt, u.picture
|
||||
FROM {rating} r
|
||||
LEFT JOIN {user} u ON r.userid = u.id
|
||||
WHERE
|
||||
r.contextid = :contextid AND
|
||||
r.itemid = :itemid
|
||||
$sort";
|
||||
|
||||
/**
|
||||
* Static method that adds rating objects to an array of items (forum posts, glossary entries etc)
|
||||
* Rating objects are available at $item->rating
|
||||
* @param $contextid the current context
|
||||
* @param $items an array of items such as forum posts or glossary items. They must have an 'id' member ie $items[0]->id
|
||||
* @param $aggregate what aggregation method should be applied. AVG, MAX etc
|
||||
* @param $scaleid the scale from which the user can select a rating
|
||||
* @param $userid the id of the current user
|
||||
*/
|
||||
public static function load_ratings($context, $items, $aggregate=RATING_AGGREGATE_AVERAGE, $scaleid=5, $userid = null, $returnurl = null) {
|
||||
global $DB, $USER, $PAGE, $CFG;
|
||||
$params['contextid'] = $context->id;
|
||||
$params['itemid'] = $itemid;
|
||||
|
||||
if(empty($items)) {
|
||||
return $DB->get_records_sql($sql, $params);
|
||||
}
|
||||
|
||||
/**
|
||||
* Static method that adds rating objects to an array of items (forum posts, glossary entries etc)
|
||||
* Rating objects are available at $item->rating
|
||||
* @param int $contextid the current context
|
||||
* @param array $items an array of items such as forum posts or glossary items. They must have an 'id' member ie $items[0]->id
|
||||
* @param $aggregate what aggregation method should be applied. AVG, MAX etc
|
||||
* @param int $scaleid the scale from which the user can select a rating
|
||||
* @param int $userid the id of the current user
|
||||
* @return returns the array of items with their ratings attached at $items[0]->rating
|
||||
*/
|
||||
public static function load_ratings($context, $items, $aggregate=RATING_AGGREGATE_AVERAGE, $scaleid=5, $userid = null, $returnurl = null) {
|
||||
global $DB, $USER, $PAGE, $CFG;
|
||||
|
||||
if(empty($items)) {
|
||||
return $items;
|
||||
}
|
||||
|
||||
if (is_null($userid)) {
|
||||
$userid = $USER->id;
|
||||
}
|
||||
|
||||
$aggregatestr = rating::rating_get_aggregation_method($aggregate);
|
||||
|
||||
//create an array of item ids
|
||||
$itemids = array();
|
||||
foreach($items as $item) {
|
||||
$itemids[] = $item->id;
|
||||
}
|
||||
|
||||
//get the items from the database
|
||||
list($itemidtest, $params) = $DB->get_in_or_equal(
|
||||
$itemids, SQL_PARAMS_NAMED, 'itemid0000');
|
||||
|
||||
$sql = "SELECT r.itemid, ur.id, ur.userid, ur.scaleid,
|
||||
$aggregatestr(r.rating) AS aggrrating,
|
||||
COUNT(r.rating) AS numratings,
|
||||
ur.rating AS usersrating
|
||||
FROM {rating} r
|
||||
LEFT JOIN {rating} ur ON ur.contextid = r.contextid AND
|
||||
ur.itemid = r.itemid AND
|
||||
ur.userid = :userid
|
||||
WHERE
|
||||
r.contextid = :contextid AND
|
||||
r.itemid $itemidtest
|
||||
GROUP BY r.itemid, ur.rating
|
||||
ORDER BY r.itemid";
|
||||
|
||||
$params['userid'] = $userid;
|
||||
$params['contextid'] = $context->id;
|
||||
|
||||
$ratingsrecords = $DB->get_records_sql($sql, $params);
|
||||
|
||||
//now create the rating sub objects
|
||||
$permissions = rating::get_rating_permissions($context);
|
||||
|
||||
$scaleobj = new stdClass();
|
||||
$scalemax = null;
|
||||
|
||||
//todo we could look for a scale id on each item to allow each item to use a different scale
|
||||
|
||||
if($scaleid < 0 ) { //if its a scale (not numeric)
|
||||
$scalerecord = $DB->get_record('scale', array('id' => -$scaleid));
|
||||
if ($scalerecord) {
|
||||
$scaleobj->scaleitems = explode(',', $scalerecord->scale);
|
||||
$scaleobj->id = $scalerecord->id;
|
||||
$scaleobj->name = $scalerecord->name;
|
||||
|
||||
$scalemax = count($scaleobj->scale)-1;
|
||||
}
|
||||
}
|
||||
else { //its numeric
|
||||
$scaleobj->scaleitems = $scaleid;
|
||||
$scaleobj->id = $scaleid;
|
||||
$scaleobj->name = null;
|
||||
|
||||
$scalemax = $scaleid;
|
||||
}
|
||||
|
||||
$settings = new stdclass(); //settings that are common to all ratings objects in this context
|
||||
$settings->scale = $scaleobj; //the scale to use now
|
||||
$settings->permissions = $permissions;
|
||||
$settings->aggregationmethod = $aggregate;
|
||||
$settings->returnurl = $returnurl;
|
||||
|
||||
$rating = null;
|
||||
foreach($items as $item) {
|
||||
$rating = null;
|
||||
//match the item with its corresponding rating
|
||||
foreach($ratingsrecords as $rec) {
|
||||
if( $item->id==$rec->itemid ) {
|
||||
//Note: rec->scaleid = the id of scale at the time the rating was submitted
|
||||
//may be different from the current scale id
|
||||
$rating = new rating($context, $item->id, $rec->scaleid, $rec->userid);
|
||||
$rating->id = $rec->id; //unset($rec->id);
|
||||
$rating->aggregate = $rec->aggrrating; //unset($rec->aggrrating);
|
||||
$rating->count = $rec->numratings; //unset($rec->numratings);
|
||||
$rating->rating = $rec->usersrating; //unset($rec->usersrating);
|
||||
break;
|
||||
}
|
||||
}
|
||||
//if there are no ratings for this item
|
||||
if( !$rating ) {
|
||||
$scaleid = $userid = null;
|
||||
$rating = new rating($context, $item->id, $scaleid, $userid);
|
||||
$rating->id = null;
|
||||
$rating->aggregate = null;
|
||||
$rating->count = 0;
|
||||
$rating->rating = null;
|
||||
|
||||
$rating->itemid = $item->id;
|
||||
$rating->userid = null;
|
||||
$rating->scaleid = null;
|
||||
}
|
||||
|
||||
$rating->settings = $settings;
|
||||
$item->rating = $rating;
|
||||
|
||||
//Below is a nasty hack presumably here to handle scales being changed (out of 10 to out of 5 for example)
|
||||
//
|
||||
// it could throw off the grading if count and sum returned a grade higher than scale
|
||||
// so to prevent it we review the results and ensure that grade does not exceed the scale, if it does we set grade = scale (i.e. full credit)
|
||||
if ($rating->rating > $scalemax) {
|
||||
$rating->rating = $scalemax;
|
||||
}
|
||||
}
|
||||
return $items;
|
||||
}
|
||||
|
||||
if (is_null($userid)) {
|
||||
$userid = $USER->id;
|
||||
/**
|
||||
* Static method that retrieves the current user's permissions to do with ratings
|
||||
* @param context $contextid the current context
|
||||
* @return returns the array of permissions
|
||||
*/
|
||||
public static function get_rating_permissions($context) {
|
||||
return array(RATING_VIEW=>has_capability('moodle/rating:view',$context), RATING_VIEW_ALL=>has_capability('moodle/rating:viewall',$context), RATING_POST=>has_capability('moodle/rating:rate',$context));
|
||||
}
|
||||
|
||||
$aggregatestr = rating::rating_get_aggregation_method($aggregate);
|
||||
|
||||
//create an array of item ids
|
||||
$itemids = array();
|
||||
foreach($items as $item) {
|
||||
$itemids[] = $item->id;
|
||||
}
|
||||
|
||||
//get the items from the database
|
||||
list($itemidtest, $params) = $DB->get_in_or_equal(
|
||||
$itemids, SQL_PARAMS_NAMED, 'itemid0000');
|
||||
|
||||
$sql = "SELECT r.itemid, ur.id, ur.userid, ur.scaleid,
|
||||
$aggregatestr(r.rating) AS aggrrating,
|
||||
COUNT(r.rating) AS numratings,
|
||||
ur.rating AS usersrating
|
||||
FROM {rating} r
|
||||
LEFT JOIN {rating} ur ON ur.contextid = r.contextid AND
|
||||
ur.itemid = r.itemid AND
|
||||
ur.userid = :userid
|
||||
WHERE
|
||||
r.contextid = :contextid AND
|
||||
r.itemid $itemidtest
|
||||
GROUP BY r.itemid, ur.rating
|
||||
ORDER BY r.itemid";
|
||||
|
||||
$params['userid'] = $userid;
|
||||
$params['contextid'] = $context->id;
|
||||
|
||||
$ratingsrecords = $DB->get_records_sql($sql, $params);
|
||||
|
||||
//now create the rating sub objects
|
||||
$permissions = rating::get_rating_permissions($context);
|
||||
|
||||
$scaleobj = new stdClass();
|
||||
$scalemax = null;
|
||||
|
||||
//todo we could look for a scale id on each item to allow each item to use a different scale
|
||||
|
||||
if($scaleid < 0 ) { //if its a scale (not numeric)
|
||||
$scalerecord = $DB->get_record('scale', array('id' => -$scaleid));
|
||||
if ($scalerecord) {
|
||||
$scaleobj->scaleitems = explode(',', $scalerecord->scale);
|
||||
$scaleobj->id = $scalerecord->id;
|
||||
$scaleobj->name = $scalerecord->name;
|
||||
|
||||
$scalemax = count($scaleobj->scale)-1;
|
||||
}
|
||||
}
|
||||
else { //its numeric
|
||||
$scaleobj->scaleitems = $scaleid;
|
||||
$scaleobj->id = $scaleid;
|
||||
$scaleobj->name = null;
|
||||
|
||||
$scalemax = $scaleid;
|
||||
}
|
||||
|
||||
$settings = new stdclass(); //settings that are common to all ratings objects in this context
|
||||
$settings->scale = $scaleobj; //the scale to use now
|
||||
$settings->permissions = $permissions;
|
||||
$settings->aggregationmethod = $aggregate;
|
||||
$settings->returnurl = $returnurl;
|
||||
|
||||
$rating = null;
|
||||
foreach($items as $item) {
|
||||
$rating = null;
|
||||
//match the item with its corresponding rating
|
||||
foreach($ratingsrecords as $rec) {
|
||||
if( $item->id==$rec->itemid ) {
|
||||
//Note: rec->scaleid = the id of scale at the time the rating was submitted
|
||||
//may be different from the current scale id
|
||||
$rating = new rating($context, $item->id, $rec->scaleid, $rec->userid);
|
||||
$rating->id = $rec->id; //unset($rec->id);
|
||||
$rating->aggregate = $rec->aggrrating; //unset($rec->aggrrating);
|
||||
$rating->count = $rec->numratings; //unset($rec->numratings);
|
||||
$rating->rating = $rec->usersrating; //unset($rec->usersrating);
|
||||
break;
|
||||
}
|
||||
}
|
||||
//if there are no ratings for this item
|
||||
if( !$rating ) {
|
||||
$scaleid = $userid = null;
|
||||
$rating = new rating($context, $item->id, $scaleid, $userid);
|
||||
$rating->id = null;
|
||||
$rating->aggregate = null;
|
||||
$rating->count = 0;
|
||||
$rating->rating = null;
|
||||
|
||||
$rating->itemid = $item->id;
|
||||
$rating->userid = null;
|
||||
$rating->scaleid = null;
|
||||
}
|
||||
|
||||
$rating->settings = $settings;
|
||||
$item->rating = $rating;
|
||||
|
||||
//Below is a nasty hack presumably here to handle scales being changed (out of 10 to out of 5 for example)
|
||||
//
|
||||
// it could throw off the grading if count and sum returned a grade higher than scale
|
||||
// so to prevent it we review the results and ensure that grade does not exceed the scale, if it does we set grade = scale (i.e. full credit)
|
||||
if ($rating->rating > $scalemax) {
|
||||
$rating->rating = $scalemax;
|
||||
}
|
||||
}
|
||||
return $items;
|
||||
}
|
||||
|
||||
/**
|
||||
* Iterate over $items (forum posts, glossary items etc) and create $item->rating, $item->rating->aggregate and $item->rating->count
|
||||
* Similar to make_context_subobj()
|
||||
* @param array $items array of items
|
||||
* @param resultset $ratings resultset. probably from ratings_load_ratings()
|
||||
*/
|
||||
private static function make_rating_subobjs( $context, $items, $ratingsrecords, $aggregate, $scaleid, $returnurl) {
|
||||
global $DB;
|
||||
|
||||
|
||||
}
|
||||
|
||||
public static function get_rating_permissions($context) {
|
||||
return array(RATING_VIEW=>has_capability('moodle/rating:view',$context), RATING_VIEW_ALL=>has_capability('moodle/rating:viewall',$context), RATING_POST=>has_capability('moodle/rating:rate',$context));
|
||||
}
|
||||
|
||||
} //end rating class definition
|
||||
Reference in New Issue
Block a user