Moodle  2.2.1
http://www.collinsharper.com
C:/xampp/htdocs/moodle/rating/lib.php
Go to the documentation of this file.
00001 <?php
00002 
00003 // This file is part of Moodle - http://moodle.org/
00004 //
00005 // Moodle is free software: you can redistribute it and/or modify
00006 // it under the terms of the GNU General Public License as published by
00007 // the Free Software Foundation, either version 3 of the License, or
00008 // (at your option) any later version.
00009 //
00010 // Moodle is distributed in the hope that it will be useful,
00011 // but WITHOUT ANY WARRANTY; without even the implied warranty of
00012 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00013 // GNU General Public License for more details.
00014 //
00015 // You should have received a copy of the GNU General Public License
00016 // along with Moodle.  If not, see <http://www.gnu.org/licenses/>.
00017 
00027 define('RATING_UNSET_RATING', -999);
00028 
00029 define ('RATING_AGGREGATE_NONE', 0); //no ratings
00030 define ('RATING_AGGREGATE_AVERAGE', 1);
00031 define ('RATING_AGGREGATE_COUNT', 2);
00032 define ('RATING_AGGREGATE_MAXIMUM', 3);
00033 define ('RATING_AGGREGATE_MINIMUM', 4);
00034 define ('RATING_AGGREGATE_SUM', 5);
00035 
00036 define ('RATING_DEFAULT_SCALE', 5);
00037 
00045 class rating implements renderable {
00046 
00051     public $context;
00052 
00057     public $component;
00058 
00064     public $ratingarea = null;
00065 
00070     public $itemid;
00071 
00076     public $scaleid;
00077 
00082     public $userid;
00083 
00088     public $settings;
00089 
00095     public $id = null;
00096 
00103     public $aggregate = null;
00104 
00111     public $count = 0;
00112 
00119     public $rating = null;
00120 
00126     public $itemtimecreated = null;
00127 
00133     public $itemuserid = null;
00134 
00151     public function __construct($options) {
00152         $this->context =    $options->context;
00153         $this->component =  $options->component;
00154         $this->ratingarea = $options->ratingarea;
00155         $this->itemid =     $options->itemid;
00156         $this->scaleid =    $options->scaleid;
00157         $this->userid =     $options->userid;
00158 
00159         if (isset($options->settings)) {
00160             $this->settings = $options->settings;
00161         }
00162         if (isset($options->id)) {
00163             $this->id = $options->id;
00164         }
00165         if (isset($options->aggregate)) {
00166             $this->aggregate = $options->aggregate;
00167         }
00168         if (isset($options->count)) {
00169             $this->count = $options->count;
00170         }
00171         if (isset($options->rating)) {
00172             $this->rating = $options->rating;
00173         }
00174     }
00175 
00181     public function update_rating($rating) {
00182         global $DB;
00183 
00184         $time = time();
00185 
00186         $data = new stdClass;
00187         $data->rating       = $rating;
00188         $data->timemodified = $time;
00189 
00190         $item = new stdclass();
00191         $item->id = $this->itemid;
00192         $items = array($item);
00193 
00194         $ratingoptions = new stdClass;
00195         $ratingoptions->context = $this->context;
00196         $ratingoptions->component = $this->component;
00197         $ratingoptions->ratingarea = $this->ratingarea;
00198         $ratingoptions->items = $items;
00199         $ratingoptions->aggregate = RATING_AGGREGATE_AVERAGE;//we dont actually care what aggregation method is applied
00200         $ratingoptions->scaleid = $this->scaleid;
00201         $ratingoptions->userid = $this->userid;
00202 
00203         $rm = new rating_manager();;
00204         $items = $rm->get_ratings($ratingoptions);
00205         $firstitem = $items[0]->rating;
00206 
00207         if (empty($firstitem->id)) {
00208             // Insert a new rating
00209             $data->contextid    = $this->context->id;
00210             $data->component    = $this->component;
00211             $data->ratingarea   = $this->ratingarea;
00212             $data->rating       = $rating;
00213             $data->scaleid      = $this->scaleid;
00214             $data->userid       = $this->userid;
00215             $data->itemid       = $this->itemid;
00216             $data->timecreated  = $time;
00217             $data->timemodified = $time;
00218             $DB->insert_record('rating', $data);
00219         } else {
00220             // Update the rating
00221             $data->id           = $firstitem->id;
00222             $DB->update_record('rating', $data);
00223         }
00224     }
00225 
00230     public function get_rating() {
00231         return $this->rating;
00232     }
00233 
00239     public function get_aggregate_string() {
00240 
00241         $aggregate = $this->aggregate;
00242         $method = $this->settings->aggregationmethod;
00243 
00244         // only display aggregate if aggregation method isn't COUNT
00245         $aggregatestr = '';
00246         if ($aggregate && $method != RATING_AGGREGATE_COUNT) {
00247             if ($method != RATING_AGGREGATE_SUM && !$this->settings->scale->isnumeric) {
00248                 $aggregatestr .= $this->settings->scale->scaleitems[round($aggregate)]; //round aggregate as we're using it as an index
00249             } else { // aggregation is SUM or the scale is numeric
00250                 $aggregatestr .= round($aggregate, 1);
00251             }
00252         }
00253 
00254         return $aggregatestr;
00255     }
00256 
00263     public function user_can_rate($userid = null) {
00264         if (empty($userid)) {
00265             global $USER;
00266             $userid = $USER->id;
00267         }
00268         // You can't rate your item
00269         if ($this->itemuserid == $userid) {
00270             return false;
00271         }
00272         // You can't rate if you don't have the system cap
00273         if (!$this->settings->permissions->rate) {
00274             return false;
00275         }
00276         // You can't rate if you don't have the plugin cap
00277         if (!$this->settings->pluginpermissions->rate) {
00278             return false;
00279         }
00280 
00281         // You can't rate if the item was outside of the assessment times
00282         $timestart = $this->settings->assesstimestart;
00283         $timefinish = $this->settings->assesstimefinish;
00284         $timecreated = $this->itemtimecreated;
00285         if (!empty($timestart) && !empty($timefinish) && ($timecreated < $timestart || $timecreated > $timefinish)) {
00286             return false;
00287         }
00288         return true;
00289     }
00290 
00297     public function user_can_view_aggregate($userid = null) {
00298         if (empty($userid)) {
00299             global $USER;
00300             $userid = $USER->id;
00301         }
00302 
00303         // if the item doesnt belong to anyone or its another user's items and they can see the aggregate on items they don't own
00304         // Note that viewany doesnt mean you can see the aggregate or ratings of your own items
00305         if ((empty($this->itemuserid) or $this->itemuserid != $userid) && $this->settings->permissions->viewany && $this->settings->pluginpermissions->viewany ) {
00306             return true;
00307         }
00308 
00309         // if its the current user's item and they have permission to view the aggregate on their own items
00310         if ($this->itemuserid == $userid && $this->settings->permissions->view && $this->settings->pluginpermissions->view) {
00311             return true;
00312         }
00313 
00314         return false;
00315     }
00316 
00326     public function get_view_ratings_url($popup = false) {
00327         $attributes = array(
00328             'contextid'  => $this->context->id,
00329             'component'  => $this->component,
00330             'ratingarea' => $this->ratingarea,
00331             'itemid'     => $this->itemid,
00332             'scaleid'    => $this->settings->scale->id
00333         );
00334         if ($popup) {
00335             $attributes['popup'] = 1;
00336         }
00337         return new moodle_url('/rating/index.php', $attributes);
00338     }
00339 
00348     public function get_rate_url($rating = null, $returnurl = null) {
00349         if (empty($returnurl)) {
00350             if (!empty($this->settings->returnurl)) {
00351                 $returnurl = $this->settings->returnurl;
00352             } else {
00353                 global $PAGE;
00354                 $returnurl = $PAGE->url;
00355             }
00356         }
00357         $args = array(
00358             'contextid'   => $this->context->id,
00359             'component'   => $this->component,
00360             'ratingarea'  => $this->ratingarea,
00361             'itemid'      => $this->itemid,
00362             'scaleid'     => $this->settings->scale->id,
00363             'returnurl'   => $returnurl,
00364             'rateduserid' => $this->itemuserid,
00365             'aggregation' => $this->settings->aggregationmethod,
00366             'sesskey'     => sesskey()
00367         );
00368         if (!empty($rating)) {
00369             $args['rating'] = $rating;
00370         }
00371         $url = new moodle_url('/rating/rate.php', $args);
00372         return $url;
00373     }
00374 
00379     //public function delete_rating() {
00380         //todo implement this if its actually needed
00381     //}
00382 } //end rating class definition
00383 
00391 class rating_manager {
00392 
00397     protected $scales = array();
00398 
00413     public function delete_ratings($options) {
00414         global $DB;
00415 
00416         if (empty($options->contextid)) {
00417             throw new coding_exception('The context option is a required option when deleting ratings.');
00418         }
00419 
00420         $conditions = array('contextid' => $options->contextid);
00421         $possibleconditions = array(
00422             'ratingid'   => 'id',
00423             'userid'     => 'userid',
00424             'itemid'     => 'itemid',
00425             'component'  => 'component',
00426             'ratingarea' => 'ratingarea'
00427         );
00428         foreach ($possibleconditions as $option => $field) {
00429             if (isset($options->{$option})) {
00430                 $conditions[$field] = $options->{$option};
00431             }
00432         }
00433         $DB->delete_records('rating', $conditions);
00434     }
00435 
00448     public function get_all_ratings_for_item($options) {
00449         global $DB;
00450 
00451         if (!isset($options->context)) {
00452             throw new coding_exception('The context option is a required option when getting ratings for an item.');
00453         }
00454         if (!isset($options->itemid)) {
00455             throw new coding_exception('The itemid option is a required option when getting ratings for an item.');
00456         }
00457         if (!isset($options->component)) {
00458             throw new coding_exception('The component option is now a required option when getting ratings for an item.');
00459         }
00460         if (!isset($options->ratingarea)) {
00461             throw new coding_exception('The ratingarea option is now a required option when getting ratings for an item.');
00462         }
00463 
00464         $sortclause = '';
00465         if( !empty($options->sort) ) {
00466             $sortclause = "ORDER BY $options->sort";
00467         }
00468 
00469         $params = array(
00470             'contextid'  => $options->context->id,
00471             'itemid'     => $options->itemid,
00472             'component'  => $options->component,
00473             'ratingarea' => $options->ratingarea,
00474         );
00475         $userfields = user_picture::fields('u', null, 'userid');
00476         $sql = "SELECT r.id, r.rating, r.itemid, r.userid, r.timemodified, r.component, r.ratingarea, $userfields
00477                   FROM {rating} r
00478              LEFT JOIN {user} u ON r.userid = u.id
00479                  WHERE r.contextid = :contextid AND
00480                        r.itemid  = :itemid AND
00481                        r.component = :component AND
00482                        r.ratingarea = :ratingarea
00483                        {$sortclause}";
00484 
00485         return $DB->get_records_sql($sql, $params);
00486     }
00487 
00504     public function get_ratings($options) {
00505         global $DB, $USER;
00506 
00507         if (!isset($options->context)) {
00508             throw new coding_exception('The context option is a required option when getting ratings.');
00509         }
00510 
00511         if (!isset($options->component)) {
00512             throw new coding_exception('The component option is a required option when getting ratings.');
00513         }
00514 
00515         if (!isset($options->ratingarea)) {
00516             throw new coding_exception('The ratingarea option is a required option when getting ratings.');
00517         }
00518 
00519         if (!isset($options->scaleid)) {
00520             throw new coding_exception('The scaleid option is a required option when getting ratings.');
00521         }
00522 
00523         if (!isset($options->items)) {
00524             throw new coding_exception('The items option is a required option when getting ratings.');
00525         } else if (empty($options->items)) {
00526             return array();
00527         }
00528 
00529         if (!isset($options->aggregate)) {
00530             throw new coding_exception('The aggregate option is a required option when getting ratings.');
00531         } else if ($options->aggregate == RATING_AGGREGATE_NONE) {
00532             // Ratings arn't enabled.
00533             return $options->items;
00534         }
00535         $aggregatestr = $this->get_aggregation_method($options->aggregate);
00536 
00537         // Default the userid to the current user if it is not set
00538         if (empty($options->userid)) {
00539             $userid = $USER->id;
00540         } else {
00541             $userid = $options->userid;
00542         }
00543 
00544         // Get the item table name, the item id field, and the item user field for the given rating item
00545         // from the related component.
00546         list($type, $name) = normalize_component($options->component);
00547         $default = array(null, 'id', 'userid');
00548         list($itemtablename, $itemidcol, $itemuseridcol) = plugin_callback($type, $name, 'rating', 'get_item_fields', array($options), $default);
00549 
00550         // Create an array of item ids
00551         $itemids = array();
00552         foreach ($options->items as $item) {
00553             $itemids[] = $item->{$itemidcol};
00554         }
00555 
00556         // get the items from the database
00557         list($itemidtest, $params) = $DB->get_in_or_equal($itemids, SQL_PARAMS_NAMED);
00558         $params['contextid'] = $options->context->id;
00559         $params['userid']    = $userid;
00560         $params['component']    = $options->component;
00561         $params['ratingarea'] = $options->ratingarea;
00562 
00563         $sql = "SELECT r.id, r.itemid, r.userid, r.scaleid, r.rating AS usersrating
00564                   FROM {rating} r
00565                  WHERE r.userid = :userid AND
00566                        r.contextid = :contextid AND
00567                        r.itemid {$itemidtest} AND
00568                        r.component = :component AND
00569                        r.ratingarea = :ratingarea
00570               ORDER BY r.itemid";
00571         $userratings = $DB->get_records_sql($sql, $params);
00572 
00573         $sql = "SELECT r.itemid, $aggregatestr(r.rating) AS aggrrating, COUNT(r.rating) AS numratings
00574                   FROM {rating} r
00575                  WHERE r.contextid = :contextid AND
00576                        r.itemid {$itemidtest} AND
00577                        r.component = :component AND
00578                        r.ratingarea = :ratingarea
00579               GROUP BY r.itemid, r.component, r.ratingarea, r.contextid
00580               ORDER BY r.itemid";
00581         $aggregateratings = $DB->get_records_sql($sql, $params);
00582 
00583         $ratingoptions = new stdClass;
00584         $ratingoptions->context = $options->context;
00585         $ratingoptions->component = $options->component;
00586         $ratingoptions->ratingarea = $options->ratingarea;
00587         $ratingoptions->settings = $this->generate_rating_settings_object($options);
00588         foreach ($options->items as $item) {
00589             $founduserrating = false;
00590             foreach($userratings as $userrating) {
00591                 //look for an existing rating from this user of this item
00592                 if ($item->{$itemidcol} == $userrating->itemid) {
00593                     // Note: rec->scaleid = the id of scale at the time the rating was submitted
00594                     // may be different from the current scale id
00595                     $ratingoptions->scaleid = $userrating->scaleid;
00596                     $ratingoptions->userid = $userrating->userid;
00597                     $ratingoptions->id = $userrating->id;
00598                     $ratingoptions->rating = min($userrating->usersrating, $ratingoptions->settings->scale->max);
00599 
00600                     $founduserrating = true;
00601                     break;
00602                 }
00603             }
00604             if (!$founduserrating) {
00605                 $ratingoptions->scaleid = null;
00606                 $ratingoptions->userid = null;
00607                 $ratingoptions->id = null;
00608                 $ratingoptions->rating =  null;
00609             }
00610 
00611             if (array_key_exists($item->{$itemidcol}, $aggregateratings)) {
00612                 $rec = $aggregateratings[$item->{$itemidcol}];
00613                 $ratingoptions->itemid = $item->{$itemidcol};
00614                 $ratingoptions->aggregate = min($rec->aggrrating, $ratingoptions->settings->scale->max);
00615                 $ratingoptions->count = $rec->numratings;
00616             } else {
00617                 $ratingoptions->itemid = $item->{$itemidcol};
00618                 $ratingoptions->aggregate = null;
00619                 $ratingoptions->count = 0;
00620             }
00621 
00622             $rating = new rating($ratingoptions);
00623             $rating->itemtimecreated = $this->get_item_time_created($item);
00624             if (!empty($item->{$itemuseridcol})) {
00625                 $rating->itemuserid = $item->{$itemuseridcol};
00626             }
00627             $item->rating = $rating;
00628         }
00629 
00630         return $options->items;
00631     }
00632 
00650     protected function generate_rating_settings_object($options) {
00651 
00652         if (!isset($options->context)) {
00653             throw new coding_exception('The context option is a required option when generating a rating settings object.');
00654         }
00655         if (!isset($options->component)) {
00656             throw new coding_exception('The component option is now a required option when generating a rating settings object.');
00657         }
00658         if (!isset($options->ratingarea)) {
00659             throw new coding_exception('The ratingarea option is now a required option when generating a rating settings object.');
00660         }
00661         if (!isset($options->aggregate)) {
00662             throw new coding_exception('The aggregate option is now a required option when generating a rating settings object.');
00663         }
00664         if (!isset($options->scaleid)) {
00665             throw new coding_exception('The scaleid option is now a required option when generating a rating settings object.');
00666         }
00667 
00668         // settings that are common to all ratings objects in this context
00669         $settings = new stdClass;
00670         $settings->scale             = $this->generate_rating_scale_object($options->scaleid); // the scale to use now
00671         $settings->aggregationmethod = $options->aggregate;
00672         $settings->assesstimestart   = null;
00673         $settings->assesstimefinish  = null;
00674 
00675         // Collect options into the settings object
00676         if (!empty($options->assesstimestart)) {
00677             $settings->assesstimestart = $options->assesstimestart;
00678         }
00679         if (!empty($options->assesstimefinish)) {
00680             $settings->assesstimefinish = $options->assesstimefinish;
00681         }
00682         if (!empty($options->returnurl)) {
00683             $settings->returnurl = $options->returnurl;
00684         }
00685 
00686         // check site capabilities
00687         $settings->permissions = new stdClass;
00688         $settings->permissions->view    = has_capability('moodle/rating:view', $options->context); // can view the aggregate of ratings of their own items
00689         $settings->permissions->viewany = has_capability('moodle/rating:viewany', $options->context); // can view the aggregate of ratings of other people's items
00690         $settings->permissions->viewall = has_capability('moodle/rating:viewall', $options->context); // can view individual ratings
00691         $settings->permissions->rate    = has_capability('moodle/rating:rate', $options->context); // can submit ratings
00692 
00693         // check module capabilities (mostly for backwards compatability with old modules that previously implemented their own ratings)
00694         $pluginpermissionsarray = $this->get_plugin_permissions_array($options->context->id, $options->component, $options->ratingarea);
00695         $settings->pluginpermissions = new stdClass;
00696         $settings->pluginpermissions->view    = $pluginpermissionsarray['view'];
00697         $settings->pluginpermissions->viewany = $pluginpermissionsarray['viewany'];
00698         $settings->pluginpermissions->viewall = $pluginpermissionsarray['viewall'];
00699         $settings->pluginpermissions->rate    = $pluginpermissionsarray['rate'];
00700 
00701         return $settings;
00702     }
00703 
00711     protected function generate_rating_scale_object($scaleid) {
00712         global $DB;
00713         if (!array_key_exists('s'.$scaleid, $this->scales)) {
00714             $scale = new stdClass;
00715             $scale->id = $scaleid;
00716             $scale->name = null;
00717             $scale->courseid = null;
00718             $scale->scaleitems = array();
00719             $scale->isnumeric = true;
00720             $scale->max = $scaleid;
00721 
00722             if ($scaleid < 0) {
00723                 // It is a proper scale (not numeric)
00724                 $scalerecord = $DB->get_record('scale', array('id' => abs($scaleid)));
00725                 if ($scalerecord) {
00726                     // We need to generate an array with string keys starting at 1
00727                     $scalearray = explode(',', $scalerecord->scale);
00728                     $c = count($scalearray);
00729                     for ($i = 0; $i < $c; $i++) {
00730                         // treat index as a string to allow sorting without changing the value
00731                         $scale->scaleitems[(string)($i + 1)] = $scalearray[$i];
00732                     }
00733                     krsort($scale->scaleitems); // have the highest grade scale item appear first
00734                     $scale->isnumeric = false;
00735                     $scale->name = $scalerecord->name;
00736                     $scale->courseid = $scalerecord->courseid;
00737                     $scale->max = count($scale->scaleitems);
00738                 }
00739             } else {
00740                 //generate an array of values for numeric scales
00741                 for($i = 0; $i <= (int)$scaleid; $i++) {
00742                     $scale->scaleitems[(string)$i] = $i;
00743                 }
00744             }
00745             $this->scales['s'.$scaleid] = $scale;
00746         }
00747         return $this->scales['s'.$scaleid];
00748     }
00749 
00760     protected function get_item_time_created($item) {
00761         if( !empty($item->created) ) {
00762             return $item->created;//the forum_posts table has created instead of timecreated
00763         }
00764         else if(!empty($item->timecreated)) {
00765             return $item->timecreated;
00766         }
00767         else {
00768             return null;
00769         }
00770     }
00771 
00790     public function get_user_grades($options) {
00791         global $DB;
00792 
00793         $contextid = null;
00794 
00795         if (!isset($options->component)) {
00796             throw new coding_exception('The component option is now a required option when getting user grades from ratings.');
00797         }
00798         if (!isset($options->ratingarea)) {
00799             throw new coding_exception('The ratingarea option is now a required option when getting user grades from ratings.');
00800         }
00801 
00802         //if the calling code doesn't supply a context id we'll have to figure it out
00803         if( !empty($options->contextid) ) {
00804             $contextid = $options->contextid;
00805         }
00806         else if( !empty($options->cmid) ) {
00807             //not implemented as not currently used although cmid is potentially available (the forum supplies it)
00808             //Is there a convenient way to get a context id from a cm id?
00809             //$cmidnumber = $options->cmidnumber;
00810         }
00811         else if ( !empty($options->modulename) && !empty($options->moduleid) ) {
00812             $modulename = $options->modulename;
00813             $moduleid   = intval($options->moduleid);
00814 
00815             //going direct to the db for the context id seems wrong
00816             list($ctxselect, $ctxjoin) = context_instance_preload_sql('cm.id', CONTEXT_MODULE, 'ctx');
00817             $sql = "SELECT cm.* $ctxselect
00818                       FROM {course_modules} cm
00819                  LEFT JOIN {modules} mo ON mo.id = cm.module
00820                  LEFT JOIN {{$modulename}} m ON m.id = cm.instance $ctxjoin
00821                      WHERE mo.name=:modulename AND
00822                            m.id=:moduleid";
00823             $contextrecord = $DB->get_record_sql($sql, array('modulename'=>$modulename, 'moduleid'=>$moduleid), '*', MUST_EXIST);
00824             $contextid = $contextrecord->ctxid;
00825         }
00826 
00827         $params = array();
00828         $params['contextid']  = $contextid;
00829         $params['component']  = $options->component;
00830         $params['ratingarea'] = $options->ratingarea;
00831         $itemtable            = $options->itemtable;
00832         $itemtableusercolumn  = $options->itemtableusercolumn;
00833         $scaleid              = $options->scaleid;
00834         $aggregationstring    = $this->get_aggregation_method($options->aggregationmethod);
00835 
00836         //if userid is not 0 we only want the grade for a single user
00837         $singleuserwhere = '';
00838         if ($options->userid != 0) {
00839             $params['userid1'] = intval($options->userid);
00840             $singleuserwhere = "AND i.{$itemtableusercolumn} = :userid1";
00841         }
00842 
00843         //MDL-24648 The where line used to be "WHERE (r.contextid is null or r.contextid=:contextid)"
00844         //r.contextid will be null for users who haven't been rated yet
00845         //no longer including users who haven't been rated to reduce memory requirements
00846         $sql = "SELECT u.id as id, u.id AS userid, $aggregationstring(r.rating) AS rawgrade
00847                   FROM {user} u
00848              LEFT JOIN {{$itemtable}} i ON u.id=i.{$itemtableusercolumn}
00849              LEFT JOIN {rating} r ON r.itemid=i.id
00850                  WHERE r.contextid = :contextid AND
00851                        r.component = :component AND
00852                        r.ratingarea = :ratingarea
00853                        $singleuserwhere
00854               GROUP BY u.id";
00855         $results = $DB->get_records_sql($sql, $params);
00856 
00857         if ($results) {
00858 
00859             $scale = null;
00860             $max = 0;
00861             if ($options->scaleid >= 0) {
00862                 //numeric
00863                 $max = $options->scaleid;
00864             } else {
00865                 //custom scales
00866                 $scale = $DB->get_record('scale', array('id' => -$options->scaleid));
00867                 if ($scale) {
00868                     $scale = explode(',', $scale->scale);
00869                     $max = count($scale);
00870                 } else {
00871                     debugging('rating_manager::get_user_grades() received a scale ID that doesnt exist');
00872                 }
00873             }
00874 
00875             // it could throw off the grading if count and sum returned a rawgrade higher than scale
00876             // 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)
00877             foreach ($results as $rid=>$result) {
00878                 if ($options->scaleid >= 0) {
00879                     //numeric
00880                     if ($result->rawgrade > $options->scaleid) {
00881                         $results[$rid]->rawgrade = $options->scaleid;
00882                     }
00883                 } else {
00884                     //scales
00885                     if (!empty($scale) && $result->rawgrade > $max) {
00886                         $results[$rid]->rawgrade = $max;
00887                     }
00888                 }
00889             }
00890         }
00891 
00892         return $results;
00893     }
00894 
00900     public function get_aggregate_types() {
00901         return array (RATING_AGGREGATE_NONE     => get_string('aggregatenone', 'rating'),
00902                       RATING_AGGREGATE_AVERAGE  => get_string('aggregateavg', 'rating'),
00903                       RATING_AGGREGATE_COUNT    => get_string('aggregatecount', 'rating'),
00904                       RATING_AGGREGATE_MAXIMUM  => get_string('aggregatemax', 'rating'),
00905                       RATING_AGGREGATE_MINIMUM  => get_string('aggregatemin', 'rating'),
00906                       RATING_AGGREGATE_SUM      => get_string('aggregatesum', 'rating'));
00907     }
00908 
00914     public function get_aggregation_method($aggregate) {
00915         $aggregatestr = null;
00916         switch($aggregate){
00917             case RATING_AGGREGATE_AVERAGE:
00918                 $aggregatestr = 'AVG';
00919                 break;
00920             case RATING_AGGREGATE_COUNT:
00921                 $aggregatestr = 'COUNT';
00922                 break;
00923             case RATING_AGGREGATE_MAXIMUM:
00924                 $aggregatestr = 'MAX';
00925                 break;
00926             case RATING_AGGREGATE_MINIMUM:
00927                 $aggregatestr = 'MIN';
00928                 break;
00929             case RATING_AGGREGATE_SUM:
00930                 $aggregatestr = 'SUM';
00931                 break;
00932             default:
00933                 $aggregatestr = 'AVG'; // Default to this to avoid real breakage - MDL-22270
00934                 debugging('Incorrect call to get_aggregation_method(), was called with incorrect aggregate method ' . $aggregate, DEBUG_DEVELOPER);
00935         }
00936         return $aggregatestr;
00937     }
00938 
00946     public function get_plugin_permissions_array($contextid, $component, $ratingarea) {
00947         $pluginpermissionsarray = null;
00948         $defaultpluginpermissions = array('rate'=>false,'view'=>false,'viewany'=>false,'viewall'=>false);//deny by default
00949         if (!empty($component)) {
00950             list($type, $name) = normalize_component($component);
00951             $pluginpermissionsarray = plugin_callback($type, $name, 'rating', 'permissions', array($contextid, $component, $ratingarea), $defaultpluginpermissions);
00952         } else {
00953             $pluginpermissionsarray = $defaultpluginpermissions;
00954         }
00955         return $pluginpermissionsarray;
00956     }
00957 
00971     public function check_rating_is_valid($params) {
00972 
00973         if (!isset($params['context'])) {
00974             throw new coding_exception('The context option is a required option when checking rating validity.');
00975         }
00976         if (!isset($params['component'])) {
00977             throw new coding_exception('The component option is now a required option when checking rating validity');
00978         }
00979         if (!isset($params['ratingarea'])) {
00980             throw new coding_exception('The ratingarea option is now a required option when checking rating validity');
00981         }
00982         if (!isset($params['itemid'])) {
00983             throw new coding_exception('The itemid option is now a required option when checking rating validity');
00984         }
00985         if (!isset($params['scaleid'])) {
00986             throw new coding_exception('The scaleid option is now a required option when checking rating validity');
00987         }
00988         if (!isset($params['rateduserid'])) {
00989             throw new coding_exception('The rateduserid option is now a required option when checking rating validity');
00990         }
00991 
00992         list($plugintype, $pluginname) = normalize_component($params['component']);
00993 
00994         //this looks for a function like forum_rating_validate() in mod_forum lib.php
00995         //wrapping the params array in another array as call_user_func_array() expands arrays into multiple arguments
00996         $isvalid = plugin_callback($plugintype, $pluginname, 'rating', 'validate', array($params), null);
00997 
00998         //if null then the callback doesn't exist
00999         if ($isvalid === null) {
01000             $isvalid = false;
01001             debugging('rating validation callback not found for component '.  clean_param($component, PARAM_ALPHANUMEXT));
01002         }
01003         return $isvalid;
01004     }
01005 
01012     public function initialise_rating_javascript(moodle_page $page) {
01013         global $CFG;
01014 
01015         //only needs to be initialized once
01016         static $done = false;
01017         if ($done) {
01018             return true;
01019         }
01020 
01021         if (!empty($CFG->enableajax)) {
01022             $page->requires->js_init_call('M.core_rating.init');
01023         }
01024         $done = true;
01025 
01026         return true;
01027     }
01028 
01035     public function get_aggregate_label($aggregationmethod) {
01036         $aggregatelabel = '';
01037         switch ($aggregationmethod) {
01038             case RATING_AGGREGATE_AVERAGE :
01039                 $aggregatelabel .= get_string("aggregateavg", "rating");
01040                 break;
01041             case RATING_AGGREGATE_COUNT :
01042                 $aggregatelabel .= get_string("aggregatecount", "rating");
01043                 break;
01044             case RATING_AGGREGATE_MAXIMUM :
01045                 $aggregatelabel .= get_string("aggregatemax", "rating");
01046                 break;
01047             case RATING_AGGREGATE_MINIMUM :
01048                 $aggregatelabel .= get_string("aggregatemin", "rating");
01049                 break;
01050             case RATING_AGGREGATE_SUM :
01051                 $aggregatelabel .= get_string("aggregatesum", "rating");
01052                 break;
01053         }
01054         $aggregatelabel .= get_string('labelsep', 'langconfig');
01055         return $aggregatelabel;
01056     }
01057 
01058 }//end rating_manager class definition
01059 
01060 class rating_exception extends moodle_exception {
01061     public $message;
01062     function __construct($errorcode) {
01063         $this->errorcode = $errorcode;
01064         $this->message = get_string($errorcode, 'error');
01065     }
01066 }
 All Data Structures Namespaces Files Functions Variables Enumerations