2010-03-16 05:57:51 +00:00
< ? php
// This file is part of Moodle - http://moodle.org/
//
// Moodle is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Moodle is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
/**
* A class representing a single rating and containing some static methods for manipulating ratings
*
2010-09-06 11:17:43 +00:00
* @ package core
* @ subpackage rating
* @ copyright 2010 Andrew Davis
* @ license http :// www . gnu . org / copyleft / gpl . html GNU GPL v3 or later
2010-03-16 05:57:51 +00:00
*/
define ( 'RATING_UNSET_RATING' , - 999 );
2010-04-22 05:15:23 +00:00
define ( 'RATING_AGGREGATE_NONE' , 0 ); //no ratings
2010-03-16 05:57:51 +00:00
define ( 'RATING_AGGREGATE_AVERAGE' , 1 );
define ( 'RATING_AGGREGATE_COUNT' , 2 );
define ( 'RATING_AGGREGATE_MAXIMUM' , 3 );
define ( 'RATING_AGGREGATE_MINIMUM' , 4 );
define ( 'RATING_AGGREGATE_SUM' , 5 );
2010-03-19 02:08:31 +00:00
define ( 'RATING_DEFAULT_SCALE' , 5 );
2010-03-18 09:26:53 +00:00
2010-03-16 05:57:51 +00:00
/**
2010-03-19 07:20:13 +00:00
* The rating class represents a single rating by a single user
2010-03-16 05:57:51 +00:00
*
* @ copyright 2010 Andrew Davis
* @ license http :// www . gnu . org / copyleft / gpl . html GNU GPL v3 or later
* @ since Moodle 2.0
*/
class rating implements renderable {
2010-03-17 09:12:13 +00:00
/**
* The context in which this rating exists
* @ var context
*/
public $context ;
/**
* The id of the item ( forum post , glossary item etc ) being rated
* @ var int
*/
public $itemid ;
/**
* The id scale ( 1 - 5 , 0 - 100 ) that was in use when the rating was submitted
* @ var int
*/
public $scaleid ;
/**
* The id of the user who submitted the rating
* @ var int
*/
public $userid ;
2010-03-18 03:47:12 +00:00
/**
* settings for this rating . Necessary to render the rating .
* @ var stdclass
*/
public $settings ;
2010-03-16 09:48:15 +00:00
/**
* Constructor .
2010-03-19 06:55:47 +00:00
* @ param object $options {
* context => context context to use for the rating [ 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 ]
* }
2010-03-16 09:48:15 +00:00
*/
2010-03-19 06:55:47 +00:00
public function __construct ( $options ) {
$this -> context = $options -> context ;
$this -> itemid = $options -> itemid ;
$this -> scaleid = $options -> scaleid ;
$this -> userid = $options -> userid ;
2010-03-16 05:57:51 +00:00
}
2010-03-16 09:48:15 +00:00
/**
* Update this rating in the database
* @ param int $rating the integer value of this rating
2010-03-18 05:54:59 +00:00
* @ return void
2010-03-16 09:48:15 +00:00
*/
public function update_rating ( $rating ) {
global $DB ;
$data = new stdclass ();
$table = 'rating' ;
$item = new stdclass ();
$item -> id = $this -> itemid ;
$items = array ( $item );
2010-03-19 06:55:47 +00:00
$ratingoptions = new stdclass ();
$ratingoptions -> context = $this -> context ;
$ratingoptions -> items = $items ;
2010-04-22 05:15:23 +00:00
$ratingoptions -> aggregate = RATING_AGGREGATE_AVERAGE ; //we dont actually care what aggregation method is applied
2010-03-19 06:55:47 +00:00
$ratingoptions -> scaleid = $this -> scaleid ;
$ratingoptions -> userid = $this -> userid ;
2010-03-19 07:20:13 +00:00
$rm = new rating_manager ();
2010-04-22 05:15:23 +00:00
$items = $rm -> get_ratings ( $ratingoptions );
if ( empty ( $items ) || empty ( $items [ 0 ] -> rating ) || empty ( $items [ 0 ] -> rating -> id ) ) {
2010-03-16 09:48:15 +00:00
$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 = $items [ 0 ] -> rating -> id ;
$data -> rating = $rating ;
$time = time ();
$data -> timemodified = $time ;
$DB -> update_record ( $table , $data );
}
2010-03-16 05:57:51 +00:00
}
2010-03-16 09:48:15 +00:00
/**
* Retreive the integer value of this rating
2010-03-18 05:54:59 +00:00
* @ return int the integer value of this rating object
2010-03-16 09:48:15 +00:00
*/
public function get_rating () {
return $this -> rating ;
2010-03-16 05:57:51 +00:00
}
2010-03-16 09:48:15 +00:00
/**
* Remove this rating from the database
2010-03-18 05:54:59 +00:00
* @ return void
2010-03-16 09:48:15 +00:00
*/
2010-04-22 05:15:23 +00:00
//public function delete_rating() {
2010-03-16 09:48:15 +00:00
//todo implement this if its actually needed
2010-04-22 05:15:23 +00:00
//}
2010-03-19 07:20:13 +00:00
} //end rating class definition
2010-03-16 05:57:51 +00:00
2010-03-19 07:20:13 +00:00
/**
* The rating_manager class provides the ability to retrieve sets of ratings from the database
*
* @ copyright 2010 Andrew Davis
* @ license http :// www . gnu . org / copyleft / gpl . html GNU GPL v3 or later
* @ since Moodle 2.0
*/
class rating_manager {
2010-04-22 05:15:23 +00:00
/**
* Delete one or more ratings . Specify either a rating id , an item id or just the context id .
* @ param object $options {
* contextid => int the context in which the ratings exist [ required ]
* ratingid => int the id of an individual rating to delete [ optional ]
2010-08-17 07:18:10 +00:00
* userid => int delete the ratings submitted by this user . May be used in conjuction with itemid [ optional ]
2010-04-22 05:15:23 +00:00
* itemid => int delete all ratings attached to this item [ optional ]
* }
* @ return void
*/
public function delete_ratings ( $options ) {
global $DB ;
2010-07-04 18:36:34 +00:00
2010-04-22 05:15:23 +00:00
if ( ! empty ( $options -> ratingid ) ) {
//delete a single rating
$DB -> delete_records ( 'rating' , array ( 'contextid' => $options -> contextid , 'id' => $options -> ratingid ) );
}
2010-08-17 07:18:10 +00:00
else if ( ! empty ( $options -> itemid ) && ! empty ( $options -> userid ) ) {
//delete the rating for an item submitted by a particular user
$DB -> delete_records ( 'rating' , array ( 'contextid' => $options -> contextid , 'itemid' => $options -> itemid , 'userid' => $options -> userid ) );
}
2010-04-22 05:15:23 +00:00
else if ( ! empty ( $options -> itemid ) ) {
//delete all ratings for an item
$DB -> delete_records ( 'rating' , array ( 'contextid' => $options -> contextid , 'itemid' => $options -> itemid ) );
}
2010-08-17 07:18:10 +00:00
else if ( ! empty ( $options -> userid ) ) {
//delete all ratings submitted by a user
$DB -> delete_records ( 'rating' , array ( 'contextid' => $options -> contextid , 'userid' => $options -> userid ) );
}
2010-04-22 05:15:23 +00:00
else {
//delete all ratings for this context
$DB -> delete_records ( 'rating' , array ( 'contextid' => $options -> contextid ) );
}
}
2010-03-16 09:48:15 +00:00
/**
2010-03-19 07:20:13 +00:00
* Returns an array of ratings for a given item ( forum post , glossary entry etc )
2010-03-19 06:55:47 +00:00
* This returns all users ratings for a single item
* @ param object $options {
* context => context the context in which the ratings exists [ required ]
* itemid => int the id of the associated item ( forum post , glossary item etc ) [ required ]
* sort => string SQL sort by clause [ optional ]
* }
2010-03-18 05:54:59 +00:00
* @ return array an array of ratings
2010-03-16 09:48:15 +00:00
*/
2010-04-22 05:15:23 +00:00
public function get_all_ratings_for_item ( $options ) {
2010-03-16 09:48:15 +00:00
global $DB ;
2010-04-22 05:15:23 +00:00
$sortclause = '' ;
if ( ! empty ( $options -> sort ) ) {
$sortclause = " ORDER BY $options->sort " ;
}
2010-07-04 18:36:34 +00:00
$userfields = user_picture :: fields ( 'u' , null , 'uid' );
$sql = " SELECT r.id, r.rating, r.itemid, r.userid, r.timemodified, $userfields
2010-03-17 03:39:54 +00:00
FROM { rating } r
LEFT JOIN { user } u ON r . userid = u . id
WHERE r . contextid = : contextid AND
r . itemid = : itemid
2010-04-22 05:15:23 +00:00
{ $sortclause } " ;
2010-03-16 09:48:15 +00:00
2010-03-19 06:55:47 +00:00
$params [ 'contextid' ] = $options -> context -> id ;
$params [ 'itemid' ] = $options -> itemid ;
2010-03-16 09:48:15 +00:00
return $DB -> get_records_sql ( $sql , $params );
2010-03-16 05:57:51 +00:00
}
2010-03-16 09:48:15 +00:00
/**
2010-03-19 07:20:13 +00:00
* Adds rating objects to an array of items ( forum posts , glossary entries etc )
2010-03-16 09:48:15 +00:00
* Rating objects are available at $item -> rating
2010-03-19 06:55:47 +00:00
* @ param object $options {
* context => context the context in which the ratings exists [ 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 ]
2010-04-22 05:15:23 +00:00
* assesstimestart => int only allow rating of items created after this timestamp [ optional ]
* assesstimefinish => int only allow rating of items created before this timestamp [ optional ]
2010-04-23 09:44:19 +00:00
* 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 ]
2010-03-18 05:54:59 +00:00
* @ return array the array of items with their ratings attached at $items [ 0 ] -> rating
2010-03-16 09:48:15 +00:00
*/
2010-04-22 05:15:23 +00:00
public function get_ratings ( $options ) {
2010-03-16 09:48:15 +00:00
global $DB , $USER , $PAGE , $CFG ;
2010-05-03 02:00:33 +00:00
//are ratings enabled?
if ( $options -> aggregate == RATING_AGGREGATE_NONE ) {
return $options -> items ;
}
$aggregatestr = $this -> get_aggregation_method ( $options -> aggregate );
2010-03-19 06:55:47 +00:00
if ( empty ( $options -> items )) {
return $options -> items ;
2010-03-16 09:48:15 +00:00
}
2010-03-16 05:57:51 +00:00
2010-07-19 09:13:13 +00:00
$userid = null ;
2010-04-22 05:15:23 +00:00
if ( empty ( $options -> userid )) {
2010-03-16 09:48:15 +00:00
$userid = $USER -> id ;
2010-04-22 05:15:23 +00:00
} else {
$userid = $options -> userid ;
2010-03-16 05:57:51 +00:00
}
2010-03-16 09:48:15 +00:00
//create an array of item ids
$itemids = array ();
2010-03-19 06:55:47 +00:00
foreach ( $options -> items as $item ) {
2010-03-16 09:48:15 +00:00
$itemids [] = $item -> id ;
2010-03-16 05:57:51 +00:00
}
2010-03-16 09:48:15 +00:00
//get the items from the database
list ( $itemidtest , $params ) = $DB -> get_in_or_equal (
$itemids , SQL_PARAMS_NAMED , 'itemid0000' );
2010-03-22 02:59:06 +00:00
//note: all the group bys arent really necessary but PostgreSQL complains
//about selecting a mixture of grouped and non-grouped columns
2010-03-16 09:48:15 +00:00
$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
2010-03-22 02:59:06 +00:00
GROUP BY r . itemid , ur . rating , ur . id , ur . userid , ur . scaleid
2010-03-16 09:48:15 +00:00
ORDER BY r . itemid " ;
2010-04-22 05:15:23 +00:00
$params [ 'userid' ] = $userid ;
2010-03-19 06:55:47 +00:00
$params [ 'contextid' ] = $options -> context -> id ;
2010-03-16 09:48:15 +00:00
$ratingsrecords = $DB -> get_records_sql ( $sql , $params );
//now create the rating sub objects
$scaleobj = new stdClass ();
$scalemax = null ;
2010-03-18 04:08:52 +00:00
//we could look for a scale id on each item to allow each item to use a different scale
2010-03-19 06:55:47 +00:00
if ( $options -> scaleid < 0 ) { //if its a scale (not numeric)
$scalerecord = $DB -> get_record ( 'scale' , array ( 'id' => - $options -> scaleid ));
2010-03-16 09:48:15 +00:00
if ( $scalerecord ) {
2010-04-22 05:15:23 +00:00
$scalearray = explode ( ',' , $scalerecord -> scale );
//is there a more efficient way to get the indexes to start at 1 instead of 0?
//this will go away when scales are refactored
$c = count ( $scalearray );
$n = null ;
for ( $i = 0 ; $i < $c ; $i ++ ) {
$n = $i + 1 ;
$scaleobj -> scaleitems [ " $n " ] = $scalearray [ $i ]; //treat index as a string to allow sorting without changing the value
}
krsort ( $scaleobj -> scaleitems ); //have the highest grade scale item appear first
$scaleobj -> id = $options -> scaleid ; //dont use the one from the record or we "forget" that its negative
2010-03-16 09:48:15 +00:00
$scaleobj -> name = $scalerecord -> name ;
2010-04-22 05:15:23 +00:00
$scaleobj -> courseid = $scalerecord -> courseid ;
2010-03-16 09:48:15 +00:00
2010-04-22 05:15:23 +00:00
$scalemax = count ( $scaleobj -> scaleitems );
2010-03-16 09:48:15 +00:00
}
}
else { //its numeric
2010-03-19 06:55:47 +00:00
$scaleobj -> scaleitems = $options -> scaleid ;
$scaleobj -> id = $options -> scaleid ;
2010-03-16 09:48:15 +00:00
$scaleobj -> name = null ;
2010-03-16 05:57:51 +00:00
2010-03-19 06:55:47 +00:00
$scalemax = $options -> scaleid ;
2010-03-16 05:57:51 +00:00
}
2010-03-18 03:47:12 +00:00
//should $settings and $settings->permissions be declared as proper classes?
2010-03-16 09:48:15 +00:00
$settings = new stdclass (); //settings that are common to all ratings objects in this context
$settings -> scale = $scaleobj ; //the scale to use now
2010-03-19 06:55:47 +00:00
$settings -> aggregationmethod = $options -> aggregate ;
if ( ! empty ( $options -> returnurl ) ) {
$settings -> returnurl = $options -> returnurl ;
}
2010-03-16 05:57:51 +00:00
2010-04-22 05:15:23 +00:00
$settings -> assesstimestart = $settings -> assesstimefinish = null ;
if ( ! empty ( $options -> assesstimestart ) ) {
$settings -> assesstimestart = $options -> assesstimestart ;
}
if ( ! empty ( $options -> assesstimefinish ) ) {
$settings -> assesstimefinish = $options -> assesstimefinish ;
}
2010-04-23 09:44:19 +00:00
//check site capabilities
2010-03-18 03:47:12 +00:00
$settings -> permissions = new stdclass ();
2010-04-23 09:44:19 +00:00
$settings -> permissions -> view = has_capability ( 'moodle/rating:view' , $options -> context ); //can view the aggregate of ratings of their own items
$settings -> permissions -> viewany = has_capability ( 'moodle/rating:viewany' , $options -> context ); //can view the aggregate of ratings of other people's items
$settings -> permissions -> viewall = has_capability ( 'moodle/rating:viewall' , $options -> context ); //can view individual ratings
$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 );
2010-07-04 18:36:34 +00:00
2010-04-23 09:44:19 +00:00
$settings -> pluginpermissions = new stdclass ();
$settings -> pluginpermissions -> view = $pluginpermissionsarray [ 'view' ];
$settings -> pluginpermissions -> viewany = $pluginpermissionsarray [ 'viewany' ];
$settings -> pluginpermissions -> viewall = $pluginpermissionsarray [ 'viewall' ];
$settings -> pluginpermissions -> rate = $pluginpermissionsarray [ 'rate' ];
2010-03-18 03:47:12 +00:00
2010-03-16 09:48:15 +00:00
$rating = null ;
2010-03-19 06:55:47 +00:00
$ratingoptions = new stdclass ();
$ratingoptions -> context = $options -> context ; //context is common to all ratings in the set
foreach ( $options -> items as $item ) {
2010-03-16 09:48:15 +00:00
$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
2010-03-19 06:55:47 +00:00
$ratingoptions -> itemid = $item -> id ;
$ratingoptions -> scaleid = $rec -> scaleid ;
$ratingoptions -> userid = $rec -> userid ;
$rating = new rating ( $ratingoptions );
2010-03-16 09:48:15 +00:00
$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);
2010-07-16 06:30:30 +00:00
$rating -> itemtimecreated = $this -> get_item_time_created ( $item );
2010-09-06 11:17:43 +00:00
2010-03-16 09:48:15 +00:00
break ;
}
}
//if there are no ratings for this item
if ( ! $rating ) {
2010-03-19 06:55:47 +00:00
$ratingoptions -> itemid = $item -> id ;
$ratingoptions -> scaleid = null ;
$ratingoptions -> userid = null ;
$rating = new rating ( $ratingoptions );
2010-03-16 09:48:15 +00:00
$rating -> id = null ;
$rating -> aggregate = null ;
$rating -> count = 0 ;
$rating -> rating = null ;
$rating -> itemid = $item -> id ;
$rating -> userid = null ;
$rating -> scaleid = null ;
2010-07-16 06:30:30 +00:00
$rating -> itemtimecreated = $this -> get_item_time_created ( $item );
2010-03-16 09:48:15 +00:00
}
2010-03-16 05:57:51 +00:00
2010-04-22 05:15:23 +00:00
if ( ! empty ( $item -> userid ) ) {
$rating -> itemuserid = $item -> userid ;
} else {
$rating -> itemuserid = null ;
}
2010-03-16 09:48:15 +00:00
$rating -> settings = $settings ;
$item -> rating = $rating ;
2010-03-16 05:57:51 +00:00
2010-03-16 09:48:15 +00:00
//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 ;
}
2010-04-22 05:15:23 +00:00
if ( $rating -> aggregate > $scalemax ) {
$rating -> aggregate = $scalemax ;
}
2010-03-16 09:48:15 +00:00
}
2010-04-22 05:15:23 +00:00
2010-03-19 06:55:47 +00:00
return $options -> items ;
2010-03-16 09:48:15 +00:00
}
2010-03-19 07:20:13 +00:00
2010-07-16 06:30:30 +00:00
private function get_item_time_created ( $item ) {
if ( ! empty ( $item -> created ) ) {
return $item -> created ; //the forum_posts table has created instead of timecreated
}
else if ( ! empty ( $item -> timecreated )) {
return $item -> timecreated ;
}
else {
return null ;
}
}
2010-04-22 05:15:23 +00:00
/**
* Returns an array of grades calculated by aggregating item ratings .
* @ param object $options {
2010-07-19 09:13:13 +00:00
* userid => int the id of the user whose items have been rated . NOT the user who submitted the ratings . 0 to update all . [ required ]
2010-04-22 05:15:23 +00:00
* aggregationmethod => int the aggregation method to apply when calculating grades ie RATING_AGGREGATE_AVERAGE [ required ]
* scaleid => int the scale from which the user can select a rating . Used for bounds checking . [ required ]
* itemtable => int the table containing the items [ required ]
* itemtableusercolum => int the column of the user table containing the item owner ' s user id [ required ]
*
* contextid => int the context in which the rated items exist [ optional ]
*
* modulename => string the name of the module [ optional ]
* moduleid => int the id of the module instance [ optional ]
*
* @ return array the array of the user ' s grades
*/
public function get_user_grades ( $options ) {
global $DB ;
$contextid = null ;
//if the calling code doesn't supply a context id we'll have to figure it out
if ( ! empty ( $options -> contextid ) ) {
$contextid = $options -> contextid ;
}
else if ( ! empty ( $options -> cmid ) ) {
//not implemented as not currently used although cmid is potentially available (the forum supplies it)
//Is there a convenient way to get a context id from a cm id?
//$cmidnumber = $options->cmidnumber;
}
else if ( ! empty ( $options -> modulename ) && ! empty ( $options -> moduleid ) ) {
$modulename = $options -> modulename ;
2010-07-19 09:13:13 +00:00
$moduleid = intval ( $options -> moduleid );
2010-07-04 18:36:34 +00:00
2010-04-22 05:15:23 +00:00
//going direct to the db for the context id seems wrong
list ( $ctxselect , $ctxjoin ) = context_instance_preload_sql ( 'cm.id' , CONTEXT_MODULE , 'ctx' );
$sql = " SELECT cm.* $ctxselect
FROM { course_modules } cm
LEFT JOIN { modules } mo ON mo . id = cm . module
LEFT JOIN {{ $modulename }} m ON m . id = cm . instance $ctxjoin
WHERE mo . name =: modulename AND m . id =: moduleid " ;
$contextrecord = $DB -> get_record_sql ( $sql , array ( 'modulename' => $modulename , 'moduleid' => $moduleid ), '*' , MUST_EXIST );
$contextid = $contextrecord -> ctxid ;
}
$params = array ();
$params [ 'contextid' ] = $contextid ;
$itemtable = $options -> itemtable ;
$itemtableusercolumn = $options -> itemtableusercolumn ;
2010-09-06 11:17:43 +00:00
$scaleid = $options -> scaleid ;
2010-04-22 05:15:23 +00:00
$aggregationstring = $this -> get_aggregation_method ( $options -> aggregationmethod );
2010-07-19 09:13:13 +00:00
//if userid is not 0 we only want the grade for a single user
$singleuserwhere = '' ;
2010-07-13 08:58:48 +00:00
if ( $options -> userid != 0 ) {
2010-07-19 09:13:13 +00:00
$params [ 'userid1' ] = intval ( $options -> userid );
$singleuserwhere = " AND i. { $itemtableusercolumn } = :userid1 " ;
2010-07-13 08:58:48 +00:00
}
2010-04-22 05:15:23 +00:00
2010-07-19 09:13:13 +00:00
//note: r.contextid will be null for users who haven't been rated yet
$sql = " SELECT u.id as id, u.id AS userid, $aggregationstring (r.rating) AS rawgrade
FROM { user } u
LEFT JOIN {{ $itemtable }} i ON u . id = i . { $itemtableusercolumn }
LEFT JOIN { rating } r ON r . itemid = i . id
WHERE ( r . contextid is null or r . contextid =: contextid )
$singleuserwhere
GROUP BY u . id " ;
2010-04-22 05:15:23 +00:00
$results = $DB -> get_records_sql ( $sql , $params );
2010-07-13 08:58:48 +00:00
2010-04-22 05:15:23 +00:00
if ( $results ) {
2010-07-13 08:58:48 +00:00
$scale = null ;
$max = 0 ;
if ( $options -> scaleid >= 0 ) {
//numeric
$max = $options -> scaleid ;
} else {
//custom scales
$scale = $DB -> get_record ( 'scale' , array ( 'id' => - $options -> scaleid ));
if ( $scale ) {
$scale = explode ( ',' , $scale -> scale );
$max = count ( $scale );
} else {
debugging ( 'rating_manager::get_user_grades() received a scale ID that doesnt exist' );
}
}
2010-04-22 05:15:23 +00:00
// it could throw off the grading if count and sum returned a rawgrade higher than scale
// so to prevent it we review the results and ensure that rawgrade does not exceed the scale, if it does we set rawgrade = scale (i.e. full credit)
foreach ( $results as $rid => $result ) {
if ( $options -> scaleid >= 0 ) {
//numeric
if ( $result -> rawgrade > $options -> scaleid ) {
$results [ $rid ] -> rawgrade = $options -> scaleid ;
}
} else {
//scales
2010-07-13 08:58:48 +00:00
if ( ! empty ( $scale ) && $result -> rawgrade > $max ) {
$results [ $rid ] -> rawgrade = $max ;
2010-04-22 05:15:23 +00:00
}
}
}
}
2010-07-13 08:58:48 +00:00
2010-04-22 05:15:23 +00:00
return $results ;
}
/**
* Returns array of aggregate types . Used by ratings .
*
* @ return array
*/
public function get_aggregate_types () {
rating MDL-23933 Removed a bunch of no longer used strings and moved rating strings into the rating lang file.
AMOS BEGIN
MOV [couldnotdeleteratings,mod_forum],[couldnotdeleteratings,core_rating]
MOV [aggregatenone,mod_forum],[aggregatenone,core_rating]
MOV [aggregateavg,mod_forum],[aggregateavg,core_rating]
MOV [aggregatecount,mod_forum],[aggregatecount,core_rating]
MOV [aggregatemax,mod_forum],[aggregatemax,core_rating]
MOV [aggregatemin,mod_forum],[aggregatemin,core_rating]
MOV [aggregatesum,mod_forum],[aggregatesum,core_rating]
AMOS END
2010-09-17 06:32:46 +00:00
return array ( RATING_AGGREGATE_NONE => get_string ( 'aggregatenone' , 'rating' ),
RATING_AGGREGATE_AVERAGE => get_string ( 'aggregateavg' , 'rating' ),
RATING_AGGREGATE_COUNT => get_string ( 'aggregatecount' , 'rating' ),
RATING_AGGREGATE_MAXIMUM => get_string ( 'aggregatemax' , 'rating' ),
RATING_AGGREGATE_MINIMUM => get_string ( 'aggregatemin' , 'rating' ),
RATING_AGGREGATE_SUM => get_string ( 'aggregatesum' , 'rating' ));
2010-04-22 05:15:23 +00:00
}
2010-03-19 07:20:13 +00:00
/**
* Converts an aggregation method constant into something that can be included in SQL
* @ param int $aggregate An aggregation constant . For example , RATING_AGGREGATE_AVERAGE .
* @ return string an SQL aggregation method
*/
2010-04-22 05:15:23 +00:00
public function get_aggregation_method ( $aggregate ) {
2010-03-19 07:20:13 +00:00
$aggregatestr = null ;
switch ( $aggregate ){
case RATING_AGGREGATE_AVERAGE :
$aggregatestr = 'AVG' ;
break ;
case RATING_AGGREGATE_COUNT :
2010-05-03 06:06:02 +00:00
$aggregatestr = 'COUNT' ;
2010-03-19 07:20:13 +00:00
break ;
case RATING_AGGREGATE_MAXIMUM :
$aggregatestr = 'MAX' ;
break ;
case RATING_AGGREGATE_MINIMUM :
$aggregatestr = 'MIN' ;
break ;
case RATING_AGGREGATE_SUM :
$aggregatestr = 'SUM' ;
break ;
2010-05-01 17:45:20 +00:00
default :
$aggregatestr = 'AVG' ; // Default to this to avoid real breakage - MDL-22270
debugging ( 'Incorrect call to get_aggregation_method(), was called with incorrect aggregate method ' . $aggregate , DEBUG_DEVELOPER );
2010-03-19 07:20:13 +00:00
}
return $aggregatestr ;
}
2010-04-23 09:44:19 +00:00
2010-05-21 07:50:38 +00:00
/**
* 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'
* @ return array rating related permissions
*/
2010-04-23 09:44:19 +00:00
public function get_plugin_permissions_array ( $contextid , $plugintype = null , $pluginname = 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 );
} else {
$pluginpermissionsarray = $defaultpluginpermissions ;
}
return $pluginpermissionsarray ;
}
2010-05-21 07:50:38 +00:00
/**
* 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' );
if ( ! empty ( $tablename )) {
$item = $DB -> get_record ( $tablename , array ( $itemidcol => $itemid ), $useridcol );
if ( $item ) {
if ( $item -> userid != $USER -> id ) {
return true ;
}
}
2010-07-04 18:36:34 +00:00
2010-05-21 07:50:38 +00:00
return false ; //item doesn't exist or belongs to the current user
} else {
return true ; //callback doesn't exist
}
}
2010-05-01 17:45:20 +00:00
} //end rating_manager class definition