rating MDL-21657 added type to phpdocs and adjusted whitespace

This commit is contained in:
Andrew Davis
2010-03-16 09:48:15 +00:00
parent 6c5fcef746
commit e1e613d52c
+245 -252
View File
@@ -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