|
Moodle
2.2.1
http://www.collinsharper.com
|
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 }