Skip to content

Commit

Permalink
Merge branch 'MDL-55786-master' of git://github.com/jleyva/moodle
Browse files Browse the repository at this point in the history
  • Loading branch information
danpoltawski committed Oct 3, 2016
2 parents 2d71da6 + afb7799 commit 8ba8b13
Show file tree
Hide file tree
Showing 5 changed files with 337 additions and 155 deletions.
8 changes: 8 additions & 0 deletions lib/db/services.php
Expand Up @@ -746,6 +746,14 @@
'capabilities' => 'moodle/rating:view',
'services' => array(MOODLE_OFFICIAL_MOBILE_SERVICE),
),
'core_rating_add_rating' => array(
'classname' => 'core_rating_external',
'methodname' => 'add_rating',
'description' => 'Rates an item.',
'type' => 'write',
'capabilities' => 'moodle/rating:rate',
'services' => array(MOODLE_OFFICIAL_MOBILE_SERVICE),
),
'core_role_assign_roles' => array(
'classname' => 'core_role_external',
'methodname' => 'assign_roles',
Expand Down
103 changes: 103 additions & 0 deletions rating/classes/external.php
Expand Up @@ -195,4 +195,107 @@ public static function get_item_ratings_returns() {
);
}

/**
* Returns description of add_rating parameters.
*
* @return external_function_parameters
* @since Moodle 3.2
*/
public static function add_rating_parameters() {
return new external_function_parameters (
array(
'contextlevel' => new external_value(PARAM_ALPHA, 'context level: course, module, user, etc...'),
'instanceid' => new external_value(PARAM_INT, 'the instance id of item associated with the context level'),
'component' => new external_value(PARAM_COMPONENT, 'component'),
'ratingarea' => new external_value(PARAM_AREA, 'rating area'),
'itemid' => new external_value(PARAM_INT, 'associated id'),
'scaleid' => new external_value(PARAM_INT, 'scale id'),
'rating' => new external_value(PARAM_INT, 'user rating'),
'rateduserid' => new external_value(PARAM_INT, 'rated user id'),
'aggregation' => new external_value(PARAM_INT, 'agreggation method', VALUE_DEFAULT, RATING_AGGREGATE_NONE)
)
);
}

/**
* Adds a rating to an item
*
* @param string $contextlevel course, module, user...
* @param int $instanceid the instance if for the context element
* @param string $component the name of the component
* @param string $ratingarea rating area
* @param int $itemid the item id
* @param int $scaleid the scale id
* @param int $rating the user rating
* @param int $rateduserid the rated user id
* @param int $aggregation the aggregation method
* @return array result and possible warnings
* @throws moodle_exception
* @since Moodle 3.2
*/
public static function add_rating($contextlevel, $instanceid, $component, $ratingarea, $itemid, $scaleid, $rating, $rateduserid,
$aggregation = RATING_AGGREGATE_NONE) {
$warnings = array();

$params = array(
'contextlevel' => $contextlevel,
'instanceid' => $instanceid,
'component' => $component,
'ratingarea' => $ratingarea,
'itemid' => $itemid,
'scaleid' => $scaleid,
'rating' => $rating,
'rateduserid' => $rateduserid,
'aggregation' => $aggregation,
);

// Validate and normalize parameters.
$params = self::validate_parameters(self::add_rating_parameters(), $params);

$context = self::get_context_from_params($params);
self::validate_context($context);
$cm = get_coursemodule_from_id(false, $context->instanceid, 0, false, MUST_EXIST);

require_capability('moodle/rating:rate', $context);

$rm = new rating_manager();
$result = $rm->add_rating($cm, $context, $params['component'], $params['ratingarea'], $params['itemid'], $params['scaleid'],
$params['rating'], $params['rateduserid'], $params['aggregation']);

if (!empty($result->error)) {
throw new moodle_exception($result->error, 'rating');
}

$returndata = array(
'success' => $result->success,
'warnings' => $warnings
);

if (isset($result->aggregate)) {
$returndata['aggregate'] = $result->aggregate;
$returndata['count'] = $result->count;
$returndata['itemid'] = $result->itemid;
}

return $returndata;
}

/**
* Returns description of add_rating result values.
*
* @return external_single_structure
* @since Moodle 3.2
*/
public static function add_rating_returns() {

return new external_single_structure(
array(
'success' => new external_value(PARAM_BOOL, 'Whether the rate was successfully created'),
'aggregate' => new external_value(PARAM_TEXT, 'New aggregate', VALUE_OPTIONAL),
'count' => new external_value(PARAM_INT, 'Ratings count', VALUE_OPTIONAL),
'itemid' => new external_value(PARAM_INT, 'Rating item id', VALUE_OPTIONAL),
'warnings' => new external_warnings(),
)
);
}
}
123 changes: 123 additions & 0 deletions rating/lib.php
Expand Up @@ -1051,6 +1051,129 @@ public function get_aggregate_label($aggregationmethod) {
return $aggregatelabel;
}

/**
* Adds a new rating
*
* @param stdClass $cm course module object
* @param stdClass $context context object
* @param string $component component name
* @param string $ratingarea rating area
* @param int $itemid the item id
* @param int $scaleid the scale id
* @param int $userrating the user rating
* @param int $rateduserid the rated user id
* @param int $aggregationmethod the aggregation method
* @since Moodle 3.2
*/
public function add_rating($cm, $context, $component, $ratingarea, $itemid, $scaleid, $userrating, $rateduserid,
$aggregationmethod) {
global $CFG, $DB, $USER;

$result = new stdClass;
// Check the module rating permissions.
// Doing this check here rather than within rating_manager::get_ratings() so we can return a error response.
$pluginpermissionsarray = $this->get_plugin_permissions_array($context->id, $component, $ratingarea);

if (!$pluginpermissionsarray['rate']) {
$result->error = 'ratepermissiondenied';
return $result;
} else {
$params = array(
'context' => $context,
'component' => $component,
'ratingarea' => $ratingarea,
'itemid' => $itemid,
'scaleid' => $scaleid,
'rating' => $userrating,
'rateduserid' => $rateduserid,
'aggregation' => $aggregationmethod
);
if (!$this->check_rating_is_valid($params)) {
$result->error = 'ratinginvalid';
return $result;
}
}

// Rating options used to update the rating then retrieve the aggregate.
$ratingoptions = new stdClass;
$ratingoptions->context = $context;
$ratingoptions->ratingarea = $ratingarea;
$ratingoptions->component = $component;
$ratingoptions->itemid = $itemid;
$ratingoptions->scaleid = $scaleid;
$ratingoptions->userid = $USER->id;

if ($userrating != RATING_UNSET_RATING) {
$rating = new rating($ratingoptions);
$rating->update_rating($userrating);
} else { // Delete the rating if the user set to "Rate..."
$options = new stdClass;
$options->contextid = $context->id;
$options->component = $component;
$options->ratingarea = $ratingarea;
$options->userid = $USER->id;
$options->itemid = $itemid;

$this->delete_ratings($options);
}

// Future possible enhancement: add a setting to turn grade updating off for those who don't want them in gradebook.
// Note that this would need to be done in both rate.php and rate_ajax.php.
if ($context->contextlevel == CONTEXT_MODULE) {
// Tell the module that its grades have changed.
$modinstance = $DB->get_record($cm->modname, array('id' => $cm->instance));
if ($modinstance) {
$modinstance->cmidnumber = $cm->id; // MDL-12961.
$functionname = $cm->modname.'_update_grades';
require_once($CFG->dirroot."/mod/{$cm->modname}/lib.php");
if (function_exists($functionname)) {
$functionname($modinstance, $rateduserid);
}
}
}

// Object to return to client as JSON.
$result->success = true;

// Need to retrieve the updated item to get its new aggregate value.
$item = new stdClass;
$item->id = $itemid;

// Most of $ratingoptions variables were previously set.
$ratingoptions->items = array($item);
$ratingoptions->aggregate = $aggregationmethod;

$items = $this->get_ratings($ratingoptions);
$firstrating = $items[0]->rating;

// See if the user has permission to see the rating aggregate.
if ($firstrating->user_can_view_aggregate()) {

// For custom scales return text not the value.
// This scales weirdness will go away when scales are refactored.
$scalearray = null;
$aggregatetoreturn = round($firstrating->aggregate, 1);

// Output a dash if aggregation method == COUNT as the count is output next to the aggregate anyway.
if ($firstrating->settings->aggregationmethod == RATING_AGGREGATE_COUNT or $firstrating->count == 0) {
$aggregatetoreturn = ' - ';
} else if ($firstrating->settings->scale->id < 0) { // If its non-numeric scale.
// Dont use the scale item if the aggregation method is sum as adding items from a custom scale makes no sense.
if ($firstrating->settings->aggregationmethod != RATING_AGGREGATE_SUM) {
$scalerecord = $DB->get_record('scale', array('id' => -$firstrating->settings->scale->id));
if ($scalerecord) {
$scalearray = explode(',', $scalerecord->scale);
$aggregatetoreturn = $scalearray[$aggregatetoreturn - 1];
}
}
}

$result->aggregate = $aggregatetoreturn;
$result->count = $firstrating->count;
$result->itemid = $itemid;
}
return $result;
}
} // End rating_manager class definition.

/**
Expand Down
107 changes: 4 additions & 103 deletions rating/rate_ajax.php
Expand Up @@ -63,110 +63,11 @@
}

$rm = new rating_manager();
$result = $rm->add_rating($cm, $context, $component, $ratingarea, $itemid, $scaleid, $userrating, $rateduserid, $aggregationmethod);

// Check the module rating permissions.
// Doing this check here rather than within rating_manager::get_ratings() so we can return a json error response.
$pluginpermissionsarray = $rm->get_plugin_permissions_array($context->id, $component, $ratingarea);

if (!$pluginpermissionsarray['rate']) {
$result->error = get_string('ratepermissiondenied', 'rating');
echo json_encode($result);
die();
} else {
$params = array(
'context' => $context,
'component' => $component,
'ratingarea' => $ratingarea,
'itemid' => $itemid,
'scaleid' => $scaleid,
'rating' => $userrating,
'rateduserid' => $rateduserid,
'aggregation' => $aggregationmethod
);
if (!$rm->check_rating_is_valid($params)) {
$result->error = get_string('ratinginvalid', 'rating');
echo json_encode($result);
die();
}
}

// Rating options used to update the rating then retrieve the aggregate.
$ratingoptions = new stdClass;
$ratingoptions->context = $context;
$ratingoptions->ratingarea = $ratingarea;
$ratingoptions->component = $component;
$ratingoptions->itemid = $itemid;
$ratingoptions->scaleid = $scaleid;
$ratingoptions->userid = $USER->id;

if ($userrating != RATING_UNSET_RATING) {
$rating = new rating($ratingoptions);
$rating->update_rating($userrating);
} else { // Delete the rating if the user set to "Rate..."
$options = new stdClass;
$options->contextid = $context->id;
$options->component = $component;
$options->ratingarea = $ratingarea;
$options->userid = $USER->id;
$options->itemid = $itemid;

$rm->delete_ratings($options);
}

// Future possible enhancement: add a setting to turn grade updating off for those who don't want them in gradebook.
// Note that this would need to be done in both rate.php and rate_ajax.php.
if ($context->contextlevel == CONTEXT_MODULE) {
// Tell the module that its grades have changed.
$modinstance = $DB->get_record($cm->modname, array('id' => $cm->instance));
if ($modinstance) {
$modinstance->cmidnumber = $cm->id; // MDL-12961.
$functionname = $cm->modname.'_update_grades';
require_once($CFG->dirroot."/mod/{$cm->modname}/lib.php");
if (function_exists($functionname)) {
$functionname($modinstance, $rateduserid);
}
}
}

// Object to return to client as JSON.
$result->success = true;

// Need to retrieve the updated item to get its new aggregate value.
$item = new stdClass;
$item->id = $itemid;

// Most of $ratingoptions variables were previously set.
$ratingoptions->items = array($item);
$ratingoptions->aggregate = $aggregationmethod;

$items = $rm->get_ratings($ratingoptions);
$firstrating = $items[0]->rating;

// See if the user has permission to see the rating aggregate.
if ($firstrating->user_can_view_aggregate()) {

// For custom scales return text not the value.
// This scales weirdness will go away when scales are refactored.
$scalearray = null;
$aggregatetoreturn = round($firstrating->aggregate, 1);

// Output a dash if aggregation method == COUNT as the count is output next to the aggregate anyway.
if ($firstrating->settings->aggregationmethod == RATING_AGGREGATE_COUNT or $firstrating->count == 0) {
$aggregatetoreturn = ' - ';
} else if ($firstrating->settings->scale->id < 0) { // If its non-numeric scale.
// Dont use the scale item if the aggregation method is sum as adding items from a custom scale makes no sense.
if ($firstrating->settings->aggregationmethod != RATING_AGGREGATE_SUM) {
$scalerecord = $DB->get_record('scale', array('id' => -$firstrating->settings->scale->id));
if ($scalerecord) {
$scalearray = explode(',', $scalerecord->scale);
$aggregatetoreturn = $scalearray[$aggregatetoreturn - 1];
}
}
}

$result->aggregate = $aggregatetoreturn;
$result->count = $firstrating->count;
$result->itemid = $itemid;
// Return translated error.
if (!empty($result->error)) {
$result->error = get_string($result->error, 'rating');
}

echo json_encode($result);

0 comments on commit 8ba8b13

Please sign in to comment.