https://docs.moodle.org/20/en/api.php?action=feedcontributions&user=Andyjdavis&feedformat=atomMoodleDocs - User contributions [en]2024-03-28T15:53:06ZUser contributionsMediaWiki 1.39.6https://docs.moodle.org/20/en/index.php?title=Moodle_2.0.3_release_notes&diff=83207Moodle 2.0.3 release notes2011-05-04T11:44:38Z<p>Andyjdavis: </p>
<hr />
<div>Release date: Not yet released<br />
<br />
===Highlights===<br />
<br />
* MDL-9376 - [[Forum_module#Question_and_Answer_forum|Q and A forum]] editing time allows students to see other posts and modify their own<br />
* MDL-4633 - The description field is now a required [[User_profile_fields|user profile field]]<br />
* MDL-26697 - Multiple [[Multimedia plugins|multimedia plugin filter]] fixes and improvements<br />
* MDL-24724 - There is now a link to send [[Messaging_2.0|messages]] on basic profile pages<br />
<br />
===User interface changes===<br />
<br />
* MDL-26388 - Duplicate files uploaded through the [[File_picker|file picker]] are now handled<br />
* MDL-26535 - New capability [[Capabilities/mod/workshop:viewauthorpublished|mod/workshop:viewauthorpublished]] for controlling visibility of workshop published submission authors<br />
* MDL-25834 - Fixes to [[Themes|themes]] for IE<br />
<br />
===Security issues===<br />
<br />
A number of security issues were resolved, including changes to APIs. Administrators are advised to update before details of security issues are revealed, which will happen one week after release.<br />
<br />
===Changes to APIs===<br />
* MDL-26838 - Multiple fixes to [[Ratings_2.0|ratings]]<br />
Modules etc wanting to make use of ratings are now required to implement two callback functions, modname_rating_permissions() and modname_rating_validate(). Full details of the callbacks are available in the [https://docs.moodle.org/en/Development:Ratings_2.0#Module_callbacks rating 2.0 documentation]<br />
<br />
===Fixes and improvements===<br />
<br />
* MDL-27251 - Added optional timeout estimation to file downloads based on file size as it can blocks upgrade<br />
* MDL-27246 - Able to checkout strings in the language customisation tool<br />
* MDL-27116 - Fixed theme directory linking<br />
* MDL-26854 - Improvements to comments<br />
* MDL-26643 - Fixed blog visibility issue after update<br />
* MDL-26768 - Grades from Lessons are now correctly set to null on non-attempt<br />
* MDL-26798 - Fixes to Dropbox repository integration<br />
<br />
A total of over 200 changes were made. See the [http://tracker.moodle.org/secure/ReleaseNote.jspa?projectId=10011&version=10537 full list of fixed issues in 2.0.3].<br />
<br />
<noinclude>==See also==<br />
*[[Moodle 2.0.2 release notes]]<br />
<br />
[[Category:Release notes]]<br />
[[Category:Moodle 2.0]]<br />
<br />
[[de:Moodle 2.0.3 Versionsinformationen]]<br />
[[es:Notas de Moodle 2.0.3]]<br />
[[fr:Notes de mise à jour de Moodle 2.0.3]]<br />
</noinclude></div>Andyjdavishttps://docs.moodle.org/20/en/index.php?title=Development:Ratings_2.0&diff=83206Development:Ratings 2.02011-05-04T11:40:34Z<p>Andyjdavis: </p>
<hr />
<div>{{Moodle 2.0}}==Objectives==<br />
<br />
Ratings are grades entered away from the gradebook. They can be entered by students and teachers and are aggregated into grades.<br />
<br />
The goals of ratings 2.0:<br />
<br />
* Manage ratings centrally<br />
* Use a consistent approach for all ratings throughout Moodle<br />
* Easily integrate ratings 2.0 with existing modules<br />
* Remove duplicate implementations of ratings functionality<br />
<br />
==Overview==<br />
<br />
The ratings 2.0 provides APIs to:<br />
# Add ratings<br />
# Update ratings<br />
# Access collected ratings for grade calculation purposes<br />
# Delete ratings<br />
<br />
==Current tracker issues==<br />
MDL-21389 Write spec for separate Ratings 2.0<br />
<br />
MDL-20514 Allow Aggregate Type in Glossary Activity<br />
<br />
MDL-21657 Implement Ratings 2.0<br />
<br />
==Interface==<br />
<br />
[[Image:RatingUI.gif]]<br />
<br />
When Javascript is enabled ajax submission means the button can be removed. In the future it would be possible to automatically interpret a 1 to 5 rating as a star rating style UI element.<br />
<br />
If the user has 'post' permission as returned by modname_rating_permissions() the dropdown box and submission button will be displayed.<br />
<br />
If the user has 'view' permissions the text to the left of the dropdown box will be displayed. The displayed text consists of the aggregate of the ratings, 4 out of 5 in the example. The number in brackets is the number of ratings that have been submitted. There have been two ratings submitted in the example.<br />
<br />
If the user has 'viewall' permissions they can click on the aggregate summary to view a list of all of the ratings that have been submitted. This is a listing of each user's profile pic, their name and the rating they submitted.<br />
<br />
<br />
==Database changes==<br />
===New tables===<br />
<br />
====Ratings====<br />
<br />
{| class="nicetable"<br />
|-<br />
! Field<br />
! Type<br />
! Default<br />
! Info<br />
|-<br />
| id<br />
| int(10)<br />
| auto-incrementing<br />
| The unique ID for this comment.<br />
|-<br />
| contextid<br />
| int(10)<br />
|<br />
| The context id defined in context table - identifies the instance of plugin owning the comment.<br />
|-<br />
| itemid<br />
| int(10)<br />
|<br />
| Some plugin specific item id (eg. forum post blog entry)<br />
|-<br />
| scaleid<br />
| int(10)<br />
|<br />
| ID of the scale (1-5, 0-100, custom) from which the user selected their rating. Including this allows smarter handling of previously entered ratings should the scales be changed.<br />
|-<br />
| rating<br />
| int(10)<br />
|<br />
| The user's rating<br />
|-<br />
| userid<br />
| int(10)<br />
|<br />
| The user who submitted the rating<br />
|-<br />
| timecreated<br />
| int(10)<br />
|<br />
| <br />
|-<br />
| timemodified<br />
| int(10)<br />
|<br />
|<br />
|}<br />
<br />
===Altered tables===<br />
The forum, glossary and data tables need to be altered to contain the required fields specificed in [https://docs.moodle.org/en/Development:Ratings_2.0#Ratings_Settings]<br />
<br />
===Removed database tables===<br />
<br />
The following tables will have their data migrated to the above ratings table and then be removed:<br />
<br />
data_ratings<br />
<br />
forum_ratings<br />
<br />
glossary_ratings<br />
<br />
===Scales===<br />
<br />
Course modules will continue to store the scale associated with their ratings. For example the glossary table has a scale column.<br />
<br />
Scales are going to be refactored as part of a separate issue. See MDL-17258.<br />
<br />
==Ratings code changes==<br />
<br />
rating/lib.php will contain...<br />
<br />
===class rating===<br />
<br />
====__construct($options)====<br />
<br />
Initialize a class instance. Requires context, itemid, scaleid and userid.<br />
<br />
====update_rating($rating)====<br />
<br />
Add or update the numerical value of the rating in the database<br />
<br />
====get_rating()====<br />
<br />
get the numerical value of the rating<br />
<br />
====delete_rating()====<br />
<br />
delete the rating. Not implemented yet as it hasn't been required.<br />
<br />
===class rating_manager===<br />
<br />
====public get_ratings($options)====<br />
Returns the supplied set of items with a rating instance attached to each item.<br />
<br />
$items is an array of objects with an id member variable ie $items[0]->id.<br />
$options requires context, items, aggregate and scaleid.<br />
<br />
items is an array of items such as forum posts or glossary items. They must have an 'id' member ie $items[0]->id.<br />
aggregate is the the aggregation method to apply. RATING_AGGREGATE_AVERAGE etc.<br />
<br />
Optionally options may include userid, returnurl, assesstimestart and assesstimefinish.<br />
<br />
If userid is omitted the current user's id will be used.<br />
returnurl is the url to return the user to after submitting a rating. Can be left null for ajax requests.<br />
assesstimestart. Only allow rating of items created after this timestamp.<br />
assesstimefinish. Only allow rating of items created before this timestamp.<br />
<br />
<code php><br />
function get_ratings($options) {<br />
global $DB, $USER;<br />
<br />
if (isnull($userid)) {<br />
$userid = $USER->id;<br />
}<br />
<br />
$itemids = array();<br />
foreach($items as $item) {<br />
$itemids[] = $item->id;<br />
}<br />
<br />
list($itemidtest, $params) = $DB->get_in_or_equal(<br />
$itemids, SQL_PARAMS_NAMED, 'itemid0000');<br />
<br />
$sql = "SELECT r.itemid, ur.id, ur.userid, ur.scaleid,<br />
$aggregatestr(r.rating) AS aggrrating,<br />
COUNT(r.rating) AS numratings,<br />
ur.rating AS usersrating<br />
FROM {ratings} r<br />
LEFT JOIN {ratings} ur ON ur.contextid = r.contextid AND<br />
ur.itemid = r.itemid AND<br />
ur.userid = :userid<br />
WHERE<br />
r.contextid = :contextid AND<br />
r.itemid $itemidtest<br />
GROUP BY r.itemid, ur.rating<br />
ORDER BY r.itemid";<br />
<br />
$params['userid'] = $userid;<br />
$params['contextid'] = $context->id;<br />
<br />
//add ratings to the items at $item->rating. Similar to make_context_subobj().<br />
//Iterate over forum $items (forum posts, glossary items etc) and create the $item->rating objects. Properties of the individual ratings, such as $item->rating->aggregate and $item->rating->rating, are stored on the rating object directly.<br />
//Settings common to the ratings are stored at $item->rating->settings->aggregationmethod (for example).<br />
}<br />
</code><br />
<br />
====get_aggregation_method($aggregate)====<br />
Converts the aggregation method constants to a string that can be included in SQL<br />
<br />
====get_all_ratings_for_item($options)====<br />
Load all ratings for a given item. Used to display a listing of submitted ratings to users with 'viewall' permission.<br />
<br />
Requires context, itemid and optionally accepts an SQL order by clause.<br />
<br />
====get_user_grades($options)====<br />
Returns a grade for a user based on other user's rating of their items.<br />
<br />
===Rendering ratings===<br />
<br />
As rendering a rating will consist of only a single function call a new method called render_rating() will be added to the core renderer.<br />
<br />
If necessary a ratings renderer could be added. Located in mod/ratings/renderer.php this new class core_rating_renderer should extend plugin_renderer_base defined in lib/outputrenderers.php Almost all renderers appear to inherit from plugin_renderer_base rather than core_renderer.<br />
<br />
=====core_renderer::render_rating(rating $rating)=====<br />
<br />
returns rating UI html snippet. Used to include ratings in pages.<br />
<br />
===Using the rating renderer===<br />
<br />
The process to render ratings is as follows:<br />
<br />
<code php><br />
// in mod/forum/discuss.php (for example)<br />
$posts = // Some forum/lib.php function call.<br />
<br />
//these are supplied by the calling module (forum etc)<br />
$aggregate = <br />
$scaleid = <br />
$userid =<br />
$returnurl = <br />
<br />
//The current scaleid comes from the forum or glossary object and may be changed at any time so supply it each time<br />
//Also, a user should only see their own ratings<br />
$posts = rating::load_ratings($context, <br />
$posts/* Optional array of items (forum posts or glossary items) with an 'id' property. If null returns all ratings for the context by the user*/, <br />
$aggregate, <br />
$scaleid, <br />
$userid, <br />
$returnurl);<br />
<br />
//ratings are now attached to the post objects. $posts[0]->rating<br />
<br />
foreach ($posts as $postid => $post) {<br />
$forumoutput->post($post);//access the rating info at $post->rating, $post->rating->aggregate and $post->rating->count<br />
}<br />
<br />
// in mod/forum/renderer.php, in the post($post) method:<br />
<br />
// ... output most of the post ... starts around line 5813 of mod/forum/lib.php<br />
echo $OUTPUT->render($item->rating);<br />
// ... output the rest.<br />
<br />
<br />
// and finally in rating/lib.php in the rating class:<br />
<br />
public function core_renderer::render_rating(rating $rating) {<br />
//return html representation of the rating<br />
}<br />
</code><br />
<br />
===Ratings Aggregation===<br />
Forums currently support multiple forms of rating aggregation such as average, maximum, sum etc. These options should be available everywhere that ratings are available.<br />
<br />
They are calculated within rating::ratings_load_ratings()<br />
<br />
===Ratings Settings===<br />
Settings for ratings are stored by the module. Each module table, for example forum, must contain the following columns.<br />
<br />
{| class="nicetable"<br />
|-<br />
! Field<br />
! Type<br />
! Default<br />
! Info<br />
|-<br />
| assessed<br />
| int(10)<br />
| <br />
| The aggregation method to apply. A value of 0 means ratings should be disabled. Currently the glossary stores an "allcanrate" flag in the assessed column. "allcanrate" will disappear in favour of proper permissions.<br />
|-<br />
| assesstimestart<br />
| int(10)<br />
|<br />
| From when can users submit ratings<br />
|-<br />
| assesstimefinish<br />
| int(10)<br />
|<br />
| When must users submit ratings by<br />
|-<br />
| scale<br />
| int(10)<br />
|<br />
| What scale to use<br />
|}<br />
<br />
The "Restrict ratings to posts with dates in this range" flag is calculated in the course/moodleforum_mod.php method moodleform::data_preprocessing() and is not stored in the database.<br />
<br />
====Settings interface====<br />
=====moodleform_mod::standard_coursemodule_elements()=====<br />
Adds elements to an instance of moodle form. The ratings elements should appear in a separate block from Common Module Settings.<br />
<br />
It will determine whether to include ratings settings by calling plugin_supports() found in lib/moodlelib.php like this...<br />
<code php><br />
if (plugin_supports('mod', $this->_modname, FEATURE_RATINGS, false)) {<br />
//include ratings elements<br />
}<br />
</code><br />
<br />
mod/%modulename%/lib.php defines a function called %modulename%_supports() that lists the elements that the module supports.<br />
<br />
FEATURE_MOD_RATINGS will have to be added to lib/moodlelib.php<br />
<br />
===Rating Submission===<br />
<br />
rating/rate.php will be the target for posted ratings. Previously each module implemented their own ratings submission. For example mod/glossary/rate.php within the glossary module.<br />
<br />
The supplied fields should consist of<br />
{| class="nicetable"<br />
|-<br />
! Field<br />
! Type<br />
! Default<br />
! Info<br />
|-<br />
| contextid<br />
| PARAM_INT<br />
|<br />
| The context id defined in context table - identifies the instance of plugin owning the comment.<br />
|-<br />
| itemid<br />
| PARAM_INT<br />
|<br />
| Some plugin specific item id (eg. forum post blog entry)<br />
|-<br />
| scaleid<br />
| PARAM_INT<br />
|<br />
| ID of the scale (1-5, 0-100, custom) from which the user selected their rating. Including this allows smarter handling of scales being changed.<br />
|-<br />
| rating<br />
| PARAM_INT<br />
|<br />
| for example, in user profile, you can comment user's description or interests, but they share the same itemid(==userid), we need comment_area to separate them<br />
|-<br />
| returnurl<br />
| PARAM_LOCALURL<br />
|<br />
| Null for ajax requests. If not null the url to which the user should be redirected after recording the rating<br />
|}<br />
<br />
The process to record a rating is as follows:<br />
<br />
<code php><br />
$permissions = forum_rating_permission();<br />
if($permissions['post']) {<br />
$rating = N; //the actual rating from the user<br />
$ratingObj = new rating($contextid, $scaleid, $userid, array($itemid));<br />
$ratingObj->set_rating($rating);<br />
//redirect to return url if supplied<br />
}<br />
<br />
//within the class rating<br />
function Rating::update_rating($rating) {<br />
$ratings = rating_system::load_ratings($scaleid, $userid, $contextid, array($itemid));<br />
if( !$ratings || sizeof($ratings)==0) {<br />
$data->contextid = $this->contextid;<br />
$data->scaleid = $this->scaleid;<br />
$data->userid = $this->userid;<br />
$data->rating = $rating;<br />
$DB->insert_record($this->table, $data);<br />
}<br />
else {<br />
$data->id = $this->id;<br />
$data->rating = $rating;<br />
$DB->update_record($this->table, $data);<br />
}<br />
<br />
}<br />
</code><br />
<br />
====Ajax submission====<br />
Ajax submission of ratings must be possible for sites with ajax enabled. ForumNG (http://moodle.org/mod/data/view.php?d=13&rid=2927) written by Sam Marshall contains an ajax implementation of the rating UI elements that may be useful to reference.<br />
<br />
Check if ajax is enabled like this...<br />
<code php><br />
if (empty($CFG->enableajax)) {<br />
//no ajax<br />
}<br />
else {<br />
//add ajax stuff<br />
}<br />
</code><br />
<br />
=== Permissions changes ===<br />
<br />
Ratings is dependent on two things: core capabilities and the result of a module callback (which may itself use module capabilities).<br />
<br />
====New ratings permissions====<br />
<br />
New system-wide ratings permissions will be added. These will be checked IN ADDITION to local permissions in existing modules.<br />
<br />
It is anticipated most new modules will just use these.<br />
<br />
The new capabilities are:<br />
<br />
moodle/rating:view - allows the user to view aggregated ratings made on their own items<br />
<br />
moodle/rating:viewany - allows the user to view aggregated ratings made on other people's items<br />
<br />
moodle/rating:viewall - allows the user to see individual ratings<br />
<br />
moodle/rating:rate - allows the user to make ratings on other people's items<br />
<br />
====Handling of old permissions====<br />
<br />
Pre-existing module-specific permissions will be extended to have matching names/behaviour with the new rating permissions.<br />
<br />
*mod/data:rate - unchanged<br />
*mod/data:viewrating - unchanged <br />
*mod/data:viewanyrating - cloned from old mod/data:viewrating<br />
*mod/data:viewallratings - cloned from old mod/data:viewrating<br />
*mod/forum:rate - unchanged<br />
*mod/forum:viewrating - unchanged<br />
*mod/forum:viewanyrating - unchanged<br />
*mod/forum:viewallratings - cloned from old mod/forum:viewanyrating<br />
*mod/glossary:rate - unchanged<br />
*mod/glossary:viewrating - unchanged<br />
*mod/glossary:viewanyrating - cloned from old mod/glossary:viewrating<br />
*mod/glossary:viewallratings - cloned from old mod/glossary:viewrating<br />
<br />
===Module callbacks===<br />
<br />
These allow modules to control how ratings behave.<br />
<br />
====modname_rating_validate====<br />
<br />
As of Moodle 2.0.3 modules must implement a function named '''modname_rating_validate''' to verify the validity of submitted ratings.<br />
<br />
This function must return true if the rating is valid or throw an instance of rating_exception if the rating is invalid. Note: false is used to indicate that the module hasn't implemented this callback.<br />
<br />
This example shows how this would work for the forum module<br />
<code php><br />
function forum_rating_validate($params) {<br />
if (!array_key_exists('itemid', $params) || !array_key_exists('context', $params) || !array_key_exists('rateduserid', $params)) {<br />
throw new rating_exception('missingparameter');<br />
}<br />
return true;<br />
}<br />
</code><br />
The rating_exception argument is the name of a string in the error language file.<br />
<br />
The $params argument contains:<br />
* context - object the context in which the rated items exists [required]<br />
* itemid - int the ID of the object being rated<br />
* scaleid - int the scale from which the user can select a rating. Used for bounds checking. [required]<br />
* rating - int the submitted rating<br />
* rateduserid - int the id of the user whose items have been rated. NOT the user who submitted the ratings. 0 to update all. [required]<br />
* aggregation - int the aggregation method to apply when calculating grades ie RATING_AGGREGATE_AVERAGE [required]<br />
<br />
====modname_rating_permissions====<br />
Modules must implement a function named '''modname_rating_permissions''' to control post and view permission. This is called prior to rendering a set of ratings. It is also called by rating/rate.php and rate/rate_ajax.php when they receive rating submissions.<br />
<br />
Modules do not need to implement this. It's mostly provided for backward compatibility with modules that had complicated ratings related logic or for modules that use settings other than capabilities to control ratings behavior.<br />
<br />
This function will return an array: array('view'=>true, 'viewany'=>true, 'viewall'=>true, 'rate'=>true)<br />
<br />
This example shows how this would work for the forum module<br />
<code php><br />
function forum_rating_permissions($context) {<br />
return array('view'=>has_capability('mod/forum:viewrating',$context), <br />
'viewany'=>has_capability('mod/forum:viewanyrating',$context), <br />
'viewall'=>has_capability('mod/forum:viewallratings',$context), <br />
'rate'=>has_capability('mod/forum:rate',$context));<br />
}<br />
</code><br />
<br />
==See also==<br />
<br />
* MDL-21657 Implement Ratings 2.0<br />
<br />
[[Category:Grades]]</div>Andyjdavishttps://docs.moodle.org/20/en/index.php?title=Moodle_2.0.3_release_notes&diff=83205Moodle 2.0.3 release notes2011-05-04T11:33:46Z<p>Andyjdavis: </p>
<hr />
<div>Release date: Not yet released<br />
<br />
===Highlights===<br />
<br />
* MDL-9376 - [[Forum_module#Question_and_Answer_forum|Q and A forum]] editing time allows students to see other posts and modify their own<br />
* MDL-4633 - The description field is now a required [[User_profile_fields|user profile field]]<br />
* MDL-26697 - Multiple [[Multimedia plugins|multimedia plugin filter]] fixes and improvements<br />
* MDL-24724 - There is now a link to send [[Messaging_2.0|messages]] on basic profile pages<br />
<br />
===User interface changes===<br />
<br />
* MDL-26388 - Duplicate files uploaded through the [[File_picker|file picker]] are now handled<br />
* MDL-26535 - New capability [[Capabilities/mod/workshop:viewauthorpublished|mod/workshop:viewauthorpublished]] for controlling visibility of workshop published submission authors<br />
* MDL-25834 - Fixes to [[Themes|themes]] for IE<br />
<br />
===Security issues===<br />
<br />
A number of security issues were resolved, including changes to APIs. Administrators are advised to update before details of security issues are revealed, which will happen one week after release.<br />
<br />
===Fixes and improvements===<br />
<br />
* MDL-27251 - Added optional timeout estimation to file downloads based on file size as it can blocks upgrade<br />
* MDL-27246 - Able to checkout strings in the language customisation tool<br />
* MDL-27116 - Fixed theme directory linking<br />
* MDL-26854 - Improvements to comments<br />
* MDL-26838 - Multiple fixes to the site-wide [[Ratings_2.0|ratings]]<br />
* MDL-26643 - Fixed blog visibility issue after update<br />
* MDL-26768 - Grades from Lessons are now correctly set to null on non-attempt<br />
* MDL-26798 - Fixes to Dropbox repository integration<br />
<br />
A total of over 200 changes were made. See the [http://tracker.moodle.org/secure/ReleaseNote.jspa?projectId=10011&version=10537 full list of fixed issues in 2.0.3].<br />
<br />
<noinclude>==See also==<br />
*[[Moodle 2.0.2 release notes]]<br />
<br />
[[Category:Release notes]]<br />
[[Category:Moodle 2.0]]<br />
<br />
[[de:Moodle 2.0.3 Versionsinformationen]]<br />
[[es:Notas de Moodle 2.0.3]]<br />
[[fr:Notes de mise à jour de Moodle 2.0.3]]<br />
</noinclude></div>Andyjdavishttps://docs.moodle.org/20/en/index.php?title=Development:Ratings_2.0&diff=83204Development:Ratings 2.02011-05-04T08:31:54Z<p>Andyjdavis: /* modname_rating_validate */</p>
<hr />
<div>{{Moodle 2.0}}==Objectives==<br />
<br />
Ratings are grades entered away from the gradebook. They can be entered by students and teachers and are aggregated into grades.<br />
<br />
The goals of ratings 2.0:<br />
<br />
* Manage ratings centrally<br />
* Use a consistent approach for all ratings throughout Moodle<br />
* Easily integrate ratings 2.0 with existing modules<br />
* Remove duplicate implementations of ratings functionality<br />
<br />
==Overview==<br />
<br />
The ratings 2.0 provides APIs to:<br />
# Add ratings<br />
# Update ratings<br />
# Access collected ratings for grade calculation purposes<br />
# Delete ratings<br />
<br />
==Current tracker issues==<br />
MDL-21389 Write spec for separate Ratings 2.0<br />
<br />
MDL-20514 Allow Aggregate Type in Glossary Activity<br />
<br />
MDL-21657 Implement Ratings 2.0<br />
<br />
==Interface==<br />
<br />
[[Image:RatingUI.gif]]<br />
<br />
When Javascript is enabled ajax submission means the button can be removed. In the future it would be possible to automatically interpret a 1 to 5 rating as a star rating style UI element.<br />
<br />
If the user has 'post' permission as returned by modname_rating_permissions() the dropdown box and submission button will be displayed.<br />
<br />
If the user has 'view' permissions the text to the left of the dropdown box will be displayed. The displayed text consists of the aggregate of the ratings, 4 out of 5 in the example. The number in brackets is the number of ratings that have been submitted. There have been two ratings submitted in the example.<br />
<br />
If the user has 'viewall' permissions they can click on the aggregate summary to view a list of all of the ratings that have been submitted. This is a listing of each user's profile pic, their name and the rating they submitted.<br />
<br />
<br />
==Database changes==<br />
===New tables===<br />
<br />
====Ratings====<br />
<br />
{| class="nicetable"<br />
|-<br />
! Field<br />
! Type<br />
! Default<br />
! Info<br />
|-<br />
| id<br />
| int(10)<br />
| auto-incrementing<br />
| The unique ID for this comment.<br />
|-<br />
| contextid<br />
| int(10)<br />
|<br />
| The context id defined in context table - identifies the instance of plugin owning the comment.<br />
|-<br />
| itemid<br />
| int(10)<br />
|<br />
| Some plugin specific item id (eg. forum post blog entry)<br />
|-<br />
| scaleid<br />
| int(10)<br />
|<br />
| ID of the scale (1-5, 0-100, custom) from which the user selected their rating. Including this allows smarter handling of previously entered ratings should the scales be changed.<br />
|-<br />
| rating<br />
| int(10)<br />
|<br />
| The user's rating<br />
|-<br />
| userid<br />
| int(10)<br />
|<br />
| The user who submitted the rating<br />
|-<br />
| timecreated<br />
| int(10)<br />
|<br />
| <br />
|-<br />
| timemodified<br />
| int(10)<br />
|<br />
|<br />
|}<br />
<br />
===Altered tables===<br />
The forum, glossary and data tables need to be altered to contain the required fields specificed in [https://docs.moodle.org/en/Development:Ratings_2.0#Ratings_Settings]<br />
<br />
===Removed database tables===<br />
<br />
The following tables will have their data migrated to the above ratings table and then be removed:<br />
<br />
data_ratings<br />
<br />
forum_ratings<br />
<br />
glossary_ratings<br />
<br />
===Scales===<br />
<br />
Course modules will continue to store the scale associated with their ratings. For example the glossary table has a scale column.<br />
<br />
Scales are going to be refactored as part of a separate issue. See MDL-17258.<br />
<br />
==Ratings code changes==<br />
<br />
rating/lib.php will contain...<br />
<br />
===class rating===<br />
<br />
====__construct($options)====<br />
<br />
Initialize a class instance. Requires context, itemid, scaleid and userid.<br />
<br />
====update_rating($rating)====<br />
<br />
Add or update the numerical value of the rating in the database<br />
<br />
====get_rating()====<br />
<br />
get the numerical value of the rating<br />
<br />
====delete_rating()====<br />
<br />
delete the rating. Not implemented yet as it hasn't been required.<br />
<br />
===class rating_manager===<br />
<br />
====public get_ratings($options)====<br />
Returns the supplied set of items with a rating instance attached to each item.<br />
<br />
$items is an array of objects with an id member variable ie $items[0]->id.<br />
$options requires context, items, aggregate and scaleid.<br />
<br />
items is an array of items such as forum posts or glossary items. They must have an 'id' member ie $items[0]->id.<br />
aggregate is the the aggregation method to apply. RATING_AGGREGATE_AVERAGE etc.<br />
<br />
Optionally options may include userid, returnurl, assesstimestart and assesstimefinish.<br />
<br />
If userid is omitted the current user's id will be used.<br />
returnurl is the url to return the user to after submitting a rating. Can be left null for ajax requests.<br />
assesstimestart. Only allow rating of items created after this timestamp.<br />
assesstimefinish. Only allow rating of items created before this timestamp.<br />
<br />
<code php><br />
function get_ratings($options) {<br />
global $DB, $USER;<br />
<br />
if (isnull($userid)) {<br />
$userid = $USER->id;<br />
}<br />
<br />
$itemids = array();<br />
foreach($items as $item) {<br />
$itemids[] = $item->id;<br />
}<br />
<br />
list($itemidtest, $params) = $DB->get_in_or_equal(<br />
$itemids, SQL_PARAMS_NAMED, 'itemid0000');<br />
<br />
$sql = "SELECT r.itemid, ur.id, ur.userid, ur.scaleid,<br />
$aggregatestr(r.rating) AS aggrrating,<br />
COUNT(r.rating) AS numratings,<br />
ur.rating AS usersrating<br />
FROM {ratings} r<br />
LEFT JOIN {ratings} ur ON ur.contextid = r.contextid AND<br />
ur.itemid = r.itemid AND<br />
ur.userid = :userid<br />
WHERE<br />
r.contextid = :contextid AND<br />
r.itemid $itemidtest<br />
GROUP BY r.itemid, ur.rating<br />
ORDER BY r.itemid";<br />
<br />
$params['userid'] = $userid;<br />
$params['contextid'] = $context->id;<br />
<br />
//add ratings to the items at $item->rating. Similar to make_context_subobj().<br />
//Iterate over forum $items (forum posts, glossary items etc) and create the $item->rating objects. Properties of the individual ratings, such as $item->rating->aggregate and $item->rating->rating, are stored on the rating object directly.<br />
//Settings common to the ratings are stored at $item->rating->settings->aggregationmethod (for example).<br />
}<br />
</code><br />
<br />
====get_aggregation_method($aggregate)====<br />
Converts the aggregation method constants to a string that can be included in SQL<br />
<br />
====get_all_ratings_for_item($options)====<br />
Load all ratings for a given item. Used to display a listing of submitted ratings to users with 'viewall' permission.<br />
<br />
Requires context, itemid and optionally accepts an SQL order by clause.<br />
<br />
====get_user_grades($options)====<br />
Returns a grade for a user based on other user's rating of their items.<br />
<br />
===Rendering ratings===<br />
<br />
As rendering a rating will consist of only a single function call a new method called render_rating() will be added to the core renderer.<br />
<br />
If necessary a ratings renderer could be added. Located in mod/ratings/renderer.php this new class core_rating_renderer should extend plugin_renderer_base defined in lib/outputrenderers.php Almost all renderers appear to inherit from plugin_renderer_base rather than core_renderer.<br />
<br />
=====core_renderer::render_rating(rating $rating)=====<br />
<br />
returns rating UI html snippet. Used to include ratings in pages.<br />
<br />
===Using the rating renderer===<br />
<br />
The process to render ratings is as follows:<br />
<br />
<code php><br />
// in mod/forum/discuss.php (for example)<br />
$posts = // Some forum/lib.php function call.<br />
<br />
//these are supplied by the calling module (forum etc)<br />
$aggregate = <br />
$scaleid = <br />
$userid =<br />
$returnurl = <br />
<br />
//The current scaleid comes from the forum or glossary object and may be changed at any time so supply it each time<br />
//Also, a user should only see their own ratings<br />
$posts = rating::load_ratings($context, <br />
$posts/* Optional array of items (forum posts or glossary items) with an 'id' property. If null returns all ratings for the context by the user*/, <br />
$aggregate, <br />
$scaleid, <br />
$userid, <br />
$returnurl);<br />
<br />
//ratings are now attached to the post objects. $posts[0]->rating<br />
<br />
foreach ($posts as $postid => $post) {<br />
$forumoutput->post($post);//access the rating info at $post->rating, $post->rating->aggregate and $post->rating->count<br />
}<br />
<br />
// in mod/forum/renderer.php, in the post($post) method:<br />
<br />
// ... output most of the post ... starts around line 5813 of mod/forum/lib.php<br />
echo $OUTPUT->render($item->rating);<br />
// ... output the rest.<br />
<br />
<br />
// and finally in rating/lib.php in the rating class:<br />
<br />
public function core_renderer::render_rating(rating $rating) {<br />
//return html representation of the rating<br />
}<br />
</code><br />
<br />
===Ratings Aggregation===<br />
Forums currently support multiple forms of rating aggregation such as average, maximum, sum etc. These options should be available everywhere that ratings are available.<br />
<br />
They are calculated within rating::ratings_load_ratings()<br />
<br />
===Ratings Settings===<br />
Settings for ratings are stored by the module. Each module table, for example forum, must contain the following columns.<br />
<br />
{| class="nicetable"<br />
|-<br />
! Field<br />
! Type<br />
! Default<br />
! Info<br />
|-<br />
| assessed<br />
| int(10)<br />
| <br />
| The aggregation method to apply. A value of 0 means ratings should be disabled. Currently the glossary stores an "allcanrate" flag in the assessed column. "allcanrate" will disappear in favour of proper permissions.<br />
|-<br />
| assesstimestart<br />
| int(10)<br />
|<br />
| From when can users submit ratings<br />
|-<br />
| assesstimefinish<br />
| int(10)<br />
|<br />
| When must users submit ratings by<br />
|-<br />
| scale<br />
| int(10)<br />
|<br />
| What scale to use<br />
|}<br />
<br />
The "Restrict ratings to posts with dates in this range" flag is calculated in the course/moodleforum_mod.php method moodleform::data_preprocessing() and is not stored in the database.<br />
<br />
====Settings interface====<br />
=====moodleform_mod::standard_coursemodule_elements()=====<br />
Adds elements to an instance of moodle form. The ratings elements should appear in a separate block from Common Module Settings.<br />
<br />
It will determine whether to include ratings settings by calling plugin_supports() found in lib/moodlelib.php like this...<br />
<code php><br />
if (plugin_supports('mod', $this->_modname, FEATURE_RATINGS, false)) {<br />
//include ratings elements<br />
}<br />
</code><br />
<br />
mod/%modulename%/lib.php defines a function called %modulename%_supports() that lists the elements that the module supports.<br />
<br />
FEATURE_MOD_RATINGS will have to be added to lib/moodlelib.php<br />
<br />
===Rating Submission===<br />
<br />
rating/rate.php will be the target for posted ratings. Previously each module implemented their own ratings submission. For example mod/glossary/rate.php within the glossary module.<br />
<br />
The supplied fields should consist of<br />
{| class="nicetable"<br />
|-<br />
! Field<br />
! Type<br />
! Default<br />
! Info<br />
|-<br />
| contextid<br />
| PARAM_INT<br />
|<br />
| The context id defined in context table - identifies the instance of plugin owning the comment.<br />
|-<br />
| itemid<br />
| PARAM_INT<br />
|<br />
| Some plugin specific item id (eg. forum post blog entry)<br />
|-<br />
| scaleid<br />
| PARAM_INT<br />
|<br />
| ID of the scale (1-5, 0-100, custom) from which the user selected their rating. Including this allows smarter handling of scales being changed.<br />
|-<br />
| rating<br />
| PARAM_INT<br />
|<br />
| for example, in user profile, you can comment user's description or interests, but they share the same itemid(==userid), we need comment_area to separate them<br />
|-<br />
| returnurl<br />
| PARAM_LOCALURL<br />
|<br />
| Null for ajax requests. If not null the url to which the user should be redirected after recording the rating<br />
|}<br />
<br />
The process to record a rating is as follows:<br />
<br />
<code php><br />
$permissions = forum_rating_permission();<br />
if($permissions['post']) {<br />
$rating = N; //the actual rating from the user<br />
$ratingObj = new rating($contextid, $scaleid, $userid, array($itemid));<br />
$ratingObj->set_rating($rating);<br />
//redirect to return url if supplied<br />
}<br />
<br />
//within the class rating<br />
function Rating::update_rating($rating) {<br />
$ratings = rating_system::load_ratings($scaleid, $userid, $contextid, array($itemid));<br />
if( !$ratings || sizeof($ratings)==0) {<br />
$data->contextid = $this->contextid;<br />
$data->scaleid = $this->scaleid;<br />
$data->userid = $this->userid;<br />
$data->rating = $rating;<br />
$DB->insert_record($this->table, $data);<br />
}<br />
else {<br />
$data->id = $this->id;<br />
$data->rating = $rating;<br />
$DB->update_record($this->table, $data);<br />
}<br />
<br />
}<br />
</code><br />
<br />
====Ajax submission====<br />
Ajax submission of ratings must be possible for sites with ajax enabled. ForumNG (http://moodle.org/mod/data/view.php?d=13&rid=2927) written by Sam Marshall contains an ajax implementation of the rating UI elements that may be useful to reference.<br />
<br />
Check if ajax is enabled like this...<br />
<code php><br />
if (empty($CFG->enableajax)) {<br />
//no ajax<br />
}<br />
else {<br />
//add ajax stuff<br />
}<br />
</code><br />
<br />
=== Permissions changes ===<br />
<br />
Ratings is dependent on two things: core capabilities and the result of a module callback (which may itself use module capabilities).<br />
<br />
====New ratings permissions====<br />
<br />
New system-wide ratings permissions will be added. These will be checked IN ADDITION to local permissions in existing modules.<br />
<br />
It is anticipated most new modules will just use these.<br />
<br />
The new capabilities are:<br />
<br />
moodle/rating:view - allows the user to view aggregated ratings made on their own items<br />
<br />
moodle/rating:viewany - allows the user to view aggregated ratings made on other people's items<br />
<br />
moodle/rating:viewall - allows the user to see individual ratings<br />
<br />
moodle/rating:rate - allows the user to make ratings on other people's items<br />
<br />
<br />
====Module callbacks====<br />
<br />
These allow modules to control how ratings behave.<br />
<br />
=====modname_rating_validate=====<br />
<br />
As of Moodle 2.0.3 modules must implement a function named '''modname_rating_validate''' to verify the validity of submitted ratings.<br />
<br />
This function must return true if the rating is valid or throw an instance of rating_exception if the rating is invalid. Note: false is used to indicate that the module hasn't implemented this callback.<br />
<br />
This example shows how this would work for the forum module<br />
<code php><br />
function forum_rating_validate($params) {<br />
if (!array_key_exists('itemid', $params) || !array_key_exists('context', $params) || !array_key_exists('rateduserid', $params)) {<br />
throw new rating_exception('missingparameter');<br />
}<br />
return true;<br />
}<br />
</code><br />
The rating_exception argument is the name of a string in the error language file.<br />
<br />
The $params argument contains:<br />
* context - object the context in which the rated items exists [required]<br />
* itemid - int the ID of the object being rated<br />
* scaleid - int the scale from which the user can select a rating. Used for bounds checking. [required]<br />
* rating - int the submitted rating<br />
* rateduserid - int the id of the user whose items have been rated. NOT the user who submitted the ratings. 0 to update all. [required]<br />
* aggregation - int the aggregation method to apply when calculating grades ie RATING_AGGREGATE_AVERAGE [required]<br />
<br />
=====modname_rating_permissions=====<br />
Modules must implement a function named '''modname_rating_permissions''' to control post and view permission. This is called prior to rendering a set of ratings. It is also called by rating/rate.php and rate/rate_ajax.php when they receive rating submissions.<br />
<br />
Modules do not need to implement this. It's mostly provided for backward compatibility with modules that had complicated ratings related logic or for modules that use settings other than capabilities to control ratings behavior.<br />
<br />
This function will return an array: array('view'=>true, 'viewany'=>true, 'viewall'=>true, 'rate'=>true)<br />
<br />
This example shows how this would work for the forum module<br />
<code php><br />
function forum_rating_permissions($context) {<br />
return array('view'=>has_capability('mod/forum:viewrating',$context), <br />
'viewany'=>has_capability('mod/forum:viewanyrating',$context), <br />
'viewall'=>has_capability('mod/forum:viewallratings',$context), <br />
'rate'=>has_capability('mod/forum:rate',$context));<br />
}<br />
</code><br />
<br />
====Handling of old permissions====<br />
<br />
Pre-existing module-specific permissions will be extended to have matching names/behaviour with the new rating permissions.<br />
<br />
*mod/data:rate - unchanged<br />
*mod/data:viewrating - unchanged <br />
*mod/data:viewanyrating - cloned from old mod/data:viewrating<br />
*mod/data:viewallratings - cloned from old mod/data:viewrating<br />
*mod/forum:rate - unchanged<br />
*mod/forum:viewrating - unchanged<br />
*mod/forum:viewanyrating - unchanged<br />
*mod/forum:viewallratings - cloned from old mod/forum:viewanyrating<br />
*mod/glossary:rate - unchanged<br />
*mod/glossary:viewrating - unchanged<br />
*mod/glossary:viewanyrating - cloned from old mod/glossary:viewrating<br />
*mod/glossary:viewallratings - cloned from old mod/glossary:viewrating<br />
<br />
==See also==<br />
<br />
* MDL-21657 Implement Ratings 2.0<br />
<br />
[[Category:Grades]]</div>Andyjdavishttps://docs.moodle.org/20/en/index.php?title=Development:Ratings_2.0&diff=83203Development:Ratings 2.02011-05-04T08:30:34Z<p>Andyjdavis: /* Module callbacks */</p>
<hr />
<div>{{Moodle 2.0}}==Objectives==<br />
<br />
Ratings are grades entered away from the gradebook. They can be entered by students and teachers and are aggregated into grades.<br />
<br />
The goals of ratings 2.0:<br />
<br />
* Manage ratings centrally<br />
* Use a consistent approach for all ratings throughout Moodle<br />
* Easily integrate ratings 2.0 with existing modules<br />
* Remove duplicate implementations of ratings functionality<br />
<br />
==Overview==<br />
<br />
The ratings 2.0 provides APIs to:<br />
# Add ratings<br />
# Update ratings<br />
# Access collected ratings for grade calculation purposes<br />
# Delete ratings<br />
<br />
==Current tracker issues==<br />
MDL-21389 Write spec for separate Ratings 2.0<br />
<br />
MDL-20514 Allow Aggregate Type in Glossary Activity<br />
<br />
MDL-21657 Implement Ratings 2.0<br />
<br />
==Interface==<br />
<br />
[[Image:RatingUI.gif]]<br />
<br />
When Javascript is enabled ajax submission means the button can be removed. In the future it would be possible to automatically interpret a 1 to 5 rating as a star rating style UI element.<br />
<br />
If the user has 'post' permission as returned by modname_rating_permissions() the dropdown box and submission button will be displayed.<br />
<br />
If the user has 'view' permissions the text to the left of the dropdown box will be displayed. The displayed text consists of the aggregate of the ratings, 4 out of 5 in the example. The number in brackets is the number of ratings that have been submitted. There have been two ratings submitted in the example.<br />
<br />
If the user has 'viewall' permissions they can click on the aggregate summary to view a list of all of the ratings that have been submitted. This is a listing of each user's profile pic, their name and the rating they submitted.<br />
<br />
<br />
==Database changes==<br />
===New tables===<br />
<br />
====Ratings====<br />
<br />
{| class="nicetable"<br />
|-<br />
! Field<br />
! Type<br />
! Default<br />
! Info<br />
|-<br />
| id<br />
| int(10)<br />
| auto-incrementing<br />
| The unique ID for this comment.<br />
|-<br />
| contextid<br />
| int(10)<br />
|<br />
| The context id defined in context table - identifies the instance of plugin owning the comment.<br />
|-<br />
| itemid<br />
| int(10)<br />
|<br />
| Some plugin specific item id (eg. forum post blog entry)<br />
|-<br />
| scaleid<br />
| int(10)<br />
|<br />
| ID of the scale (1-5, 0-100, custom) from which the user selected their rating. Including this allows smarter handling of previously entered ratings should the scales be changed.<br />
|-<br />
| rating<br />
| int(10)<br />
|<br />
| The user's rating<br />
|-<br />
| userid<br />
| int(10)<br />
|<br />
| The user who submitted the rating<br />
|-<br />
| timecreated<br />
| int(10)<br />
|<br />
| <br />
|-<br />
| timemodified<br />
| int(10)<br />
|<br />
|<br />
|}<br />
<br />
===Altered tables===<br />
The forum, glossary and data tables need to be altered to contain the required fields specificed in [https://docs.moodle.org/en/Development:Ratings_2.0#Ratings_Settings]<br />
<br />
===Removed database tables===<br />
<br />
The following tables will have their data migrated to the above ratings table and then be removed:<br />
<br />
data_ratings<br />
<br />
forum_ratings<br />
<br />
glossary_ratings<br />
<br />
===Scales===<br />
<br />
Course modules will continue to store the scale associated with their ratings. For example the glossary table has a scale column.<br />
<br />
Scales are going to be refactored as part of a separate issue. See MDL-17258.<br />
<br />
==Ratings code changes==<br />
<br />
rating/lib.php will contain...<br />
<br />
===class rating===<br />
<br />
====__construct($options)====<br />
<br />
Initialize a class instance. Requires context, itemid, scaleid and userid.<br />
<br />
====update_rating($rating)====<br />
<br />
Add or update the numerical value of the rating in the database<br />
<br />
====get_rating()====<br />
<br />
get the numerical value of the rating<br />
<br />
====delete_rating()====<br />
<br />
delete the rating. Not implemented yet as it hasn't been required.<br />
<br />
===class rating_manager===<br />
<br />
====public get_ratings($options)====<br />
Returns the supplied set of items with a rating instance attached to each item.<br />
<br />
$items is an array of objects with an id member variable ie $items[0]->id.<br />
$options requires context, items, aggregate and scaleid.<br />
<br />
items is an array of items such as forum posts or glossary items. They must have an 'id' member ie $items[0]->id.<br />
aggregate is the the aggregation method to apply. RATING_AGGREGATE_AVERAGE etc.<br />
<br />
Optionally options may include userid, returnurl, assesstimestart and assesstimefinish.<br />
<br />
If userid is omitted the current user's id will be used.<br />
returnurl is the url to return the user to after submitting a rating. Can be left null for ajax requests.<br />
assesstimestart. Only allow rating of items created after this timestamp.<br />
assesstimefinish. Only allow rating of items created before this timestamp.<br />
<br />
<code php><br />
function get_ratings($options) {<br />
global $DB, $USER;<br />
<br />
if (isnull($userid)) {<br />
$userid = $USER->id;<br />
}<br />
<br />
$itemids = array();<br />
foreach($items as $item) {<br />
$itemids[] = $item->id;<br />
}<br />
<br />
list($itemidtest, $params) = $DB->get_in_or_equal(<br />
$itemids, SQL_PARAMS_NAMED, 'itemid0000');<br />
<br />
$sql = "SELECT r.itemid, ur.id, ur.userid, ur.scaleid,<br />
$aggregatestr(r.rating) AS aggrrating,<br />
COUNT(r.rating) AS numratings,<br />
ur.rating AS usersrating<br />
FROM {ratings} r<br />
LEFT JOIN {ratings} ur ON ur.contextid = r.contextid AND<br />
ur.itemid = r.itemid AND<br />
ur.userid = :userid<br />
WHERE<br />
r.contextid = :contextid AND<br />
r.itemid $itemidtest<br />
GROUP BY r.itemid, ur.rating<br />
ORDER BY r.itemid";<br />
<br />
$params['userid'] = $userid;<br />
$params['contextid'] = $context->id;<br />
<br />
//add ratings to the items at $item->rating. Similar to make_context_subobj().<br />
//Iterate over forum $items (forum posts, glossary items etc) and create the $item->rating objects. Properties of the individual ratings, such as $item->rating->aggregate and $item->rating->rating, are stored on the rating object directly.<br />
//Settings common to the ratings are stored at $item->rating->settings->aggregationmethod (for example).<br />
}<br />
</code><br />
<br />
====get_aggregation_method($aggregate)====<br />
Converts the aggregation method constants to a string that can be included in SQL<br />
<br />
====get_all_ratings_for_item($options)====<br />
Load all ratings for a given item. Used to display a listing of submitted ratings to users with 'viewall' permission.<br />
<br />
Requires context, itemid and optionally accepts an SQL order by clause.<br />
<br />
====get_user_grades($options)====<br />
Returns a grade for a user based on other user's rating of their items.<br />
<br />
===Rendering ratings===<br />
<br />
As rendering a rating will consist of only a single function call a new method called render_rating() will be added to the core renderer.<br />
<br />
If necessary a ratings renderer could be added. Located in mod/ratings/renderer.php this new class core_rating_renderer should extend plugin_renderer_base defined in lib/outputrenderers.php Almost all renderers appear to inherit from plugin_renderer_base rather than core_renderer.<br />
<br />
=====core_renderer::render_rating(rating $rating)=====<br />
<br />
returns rating UI html snippet. Used to include ratings in pages.<br />
<br />
===Using the rating renderer===<br />
<br />
The process to render ratings is as follows:<br />
<br />
<code php><br />
// in mod/forum/discuss.php (for example)<br />
$posts = // Some forum/lib.php function call.<br />
<br />
//these are supplied by the calling module (forum etc)<br />
$aggregate = <br />
$scaleid = <br />
$userid =<br />
$returnurl = <br />
<br />
//The current scaleid comes from the forum or glossary object and may be changed at any time so supply it each time<br />
//Also, a user should only see their own ratings<br />
$posts = rating::load_ratings($context, <br />
$posts/* Optional array of items (forum posts or glossary items) with an 'id' property. If null returns all ratings for the context by the user*/, <br />
$aggregate, <br />
$scaleid, <br />
$userid, <br />
$returnurl);<br />
<br />
//ratings are now attached to the post objects. $posts[0]->rating<br />
<br />
foreach ($posts as $postid => $post) {<br />
$forumoutput->post($post);//access the rating info at $post->rating, $post->rating->aggregate and $post->rating->count<br />
}<br />
<br />
// in mod/forum/renderer.php, in the post($post) method:<br />
<br />
// ... output most of the post ... starts around line 5813 of mod/forum/lib.php<br />
echo $OUTPUT->render($item->rating);<br />
// ... output the rest.<br />
<br />
<br />
// and finally in rating/lib.php in the rating class:<br />
<br />
public function core_renderer::render_rating(rating $rating) {<br />
//return html representation of the rating<br />
}<br />
</code><br />
<br />
===Ratings Aggregation===<br />
Forums currently support multiple forms of rating aggregation such as average, maximum, sum etc. These options should be available everywhere that ratings are available.<br />
<br />
They are calculated within rating::ratings_load_ratings()<br />
<br />
===Ratings Settings===<br />
Settings for ratings are stored by the module. Each module table, for example forum, must contain the following columns.<br />
<br />
{| class="nicetable"<br />
|-<br />
! Field<br />
! Type<br />
! Default<br />
! Info<br />
|-<br />
| assessed<br />
| int(10)<br />
| <br />
| The aggregation method to apply. A value of 0 means ratings should be disabled. Currently the glossary stores an "allcanrate" flag in the assessed column. "allcanrate" will disappear in favour of proper permissions.<br />
|-<br />
| assesstimestart<br />
| int(10)<br />
|<br />
| From when can users submit ratings<br />
|-<br />
| assesstimefinish<br />
| int(10)<br />
|<br />
| When must users submit ratings by<br />
|-<br />
| scale<br />
| int(10)<br />
|<br />
| What scale to use<br />
|}<br />
<br />
The "Restrict ratings to posts with dates in this range" flag is calculated in the course/moodleforum_mod.php method moodleform::data_preprocessing() and is not stored in the database.<br />
<br />
====Settings interface====<br />
=====moodleform_mod::standard_coursemodule_elements()=====<br />
Adds elements to an instance of moodle form. The ratings elements should appear in a separate block from Common Module Settings.<br />
<br />
It will determine whether to include ratings settings by calling plugin_supports() found in lib/moodlelib.php like this...<br />
<code php><br />
if (plugin_supports('mod', $this->_modname, FEATURE_RATINGS, false)) {<br />
//include ratings elements<br />
}<br />
</code><br />
<br />
mod/%modulename%/lib.php defines a function called %modulename%_supports() that lists the elements that the module supports.<br />
<br />
FEATURE_MOD_RATINGS will have to be added to lib/moodlelib.php<br />
<br />
===Rating Submission===<br />
<br />
rating/rate.php will be the target for posted ratings. Previously each module implemented their own ratings submission. For example mod/glossary/rate.php within the glossary module.<br />
<br />
The supplied fields should consist of<br />
{| class="nicetable"<br />
|-<br />
! Field<br />
! Type<br />
! Default<br />
! Info<br />
|-<br />
| contextid<br />
| PARAM_INT<br />
|<br />
| The context id defined in context table - identifies the instance of plugin owning the comment.<br />
|-<br />
| itemid<br />
| PARAM_INT<br />
|<br />
| Some plugin specific item id (eg. forum post blog entry)<br />
|-<br />
| scaleid<br />
| PARAM_INT<br />
|<br />
| ID of the scale (1-5, 0-100, custom) from which the user selected their rating. Including this allows smarter handling of scales being changed.<br />
|-<br />
| rating<br />
| PARAM_INT<br />
|<br />
| for example, in user profile, you can comment user's description or interests, but they share the same itemid(==userid), we need comment_area to separate them<br />
|-<br />
| returnurl<br />
| PARAM_LOCALURL<br />
|<br />
| Null for ajax requests. If not null the url to which the user should be redirected after recording the rating<br />
|}<br />
<br />
The process to record a rating is as follows:<br />
<br />
<code php><br />
$permissions = forum_rating_permission();<br />
if($permissions['post']) {<br />
$rating = N; //the actual rating from the user<br />
$ratingObj = new rating($contextid, $scaleid, $userid, array($itemid));<br />
$ratingObj->set_rating($rating);<br />
//redirect to return url if supplied<br />
}<br />
<br />
//within the class rating<br />
function Rating::update_rating($rating) {<br />
$ratings = rating_system::load_ratings($scaleid, $userid, $contextid, array($itemid));<br />
if( !$ratings || sizeof($ratings)==0) {<br />
$data->contextid = $this->contextid;<br />
$data->scaleid = $this->scaleid;<br />
$data->userid = $this->userid;<br />
$data->rating = $rating;<br />
$DB->insert_record($this->table, $data);<br />
}<br />
else {<br />
$data->id = $this->id;<br />
$data->rating = $rating;<br />
$DB->update_record($this->table, $data);<br />
}<br />
<br />
}<br />
</code><br />
<br />
====Ajax submission====<br />
Ajax submission of ratings must be possible for sites with ajax enabled. ForumNG (http://moodle.org/mod/data/view.php?d=13&rid=2927) written by Sam Marshall contains an ajax implementation of the rating UI elements that may be useful to reference.<br />
<br />
Check if ajax is enabled like this...<br />
<code php><br />
if (empty($CFG->enableajax)) {<br />
//no ajax<br />
}<br />
else {<br />
//add ajax stuff<br />
}<br />
</code><br />
<br />
=== Permissions changes ===<br />
<br />
Ratings is dependent on two things: core capabilities and the result of a module callback (which may itself use module capabilities).<br />
<br />
====New ratings permissions====<br />
<br />
New system-wide ratings permissions will be added. These will be checked IN ADDITION to local permissions in existing modules.<br />
<br />
It is anticipated most new modules will just use these.<br />
<br />
The new capabilities are:<br />
<br />
moodle/rating:view - allows the user to view aggregated ratings made on their own items<br />
<br />
moodle/rating:viewany - allows the user to view aggregated ratings made on other people's items<br />
<br />
moodle/rating:viewall - allows the user to see individual ratings<br />
<br />
moodle/rating:rate - allows the user to make ratings on other people's items<br />
<br />
<br />
====Module callbacks====<br />
<br />
These allow modules to control how ratings behave.<br />
<br />
=====modname_rating_validate=====<br />
<br />
As of Moodle 2.0.3 modules must implement a function named '''modname_rating_validate''' to verify the validity of submitted ratings.<br />
<br />
This function must return true if the rating is valid or throw an instance of rating_exception if the rating is invalid. Note: false is used to indicate that the module hasn't implemented this callback.<br />
<br />
This example shows how this would work for the forum module<br />
<code php><br />
function forum_rating_validate($params) {<br />
if (!array_key_exists('itemid', $params) || !array_key_exists('context', $params) || !array_key_exists('rateduserid', $params)) {<br />
throw new rating_exception('missingparameter');<br />
}<br />
return true;<br />
}<br />
</code><br />
<br />
The $params argument contains:<br />
* context - object the context in which the rated items exists [required]<br />
* itemid - int the ID of the object being rated<br />
* scaleid - int the scale from which the user can select a rating. Used for bounds checking. [required]<br />
* rating - int the submitted rating<br />
* rateduserid - int the id of the user whose items have been rated. NOT the user who submitted the ratings. 0 to update all. [required]<br />
* aggregation - int the aggregation method to apply when calculating grades ie RATING_AGGREGATE_AVERAGE [required]<br />
<br />
<br />
=====modname_rating_permissions=====<br />
Modules must implement a function named '''modname_rating_permissions''' to control post and view permission. This is called prior to rendering a set of ratings. It is also called by rating/rate.php and rate/rate_ajax.php when they receive rating submissions.<br />
<br />
Modules do not need to implement this. It's mostly provided for backward compatibility with modules that had complicated ratings related logic or for modules that use settings other than capabilities to control ratings behavior.<br />
<br />
This function will return an array: array('view'=>true, 'viewany'=>true, 'viewall'=>true, 'rate'=>true)<br />
<br />
This example shows how this would work for the forum module<br />
<code php><br />
function forum_rating_permissions($context) {<br />
return array('view'=>has_capability('mod/forum:viewrating',$context), <br />
'viewany'=>has_capability('mod/forum:viewanyrating',$context), <br />
'viewall'=>has_capability('mod/forum:viewallratings',$context), <br />
'rate'=>has_capability('mod/forum:rate',$context));<br />
}<br />
</code><br />
<br />
====Handling of old permissions====<br />
<br />
Pre-existing module-specific permissions will be extended to have matching names/behaviour with the new rating permissions.<br />
<br />
*mod/data:rate - unchanged<br />
*mod/data:viewrating - unchanged <br />
*mod/data:viewanyrating - cloned from old mod/data:viewrating<br />
*mod/data:viewallratings - cloned from old mod/data:viewrating<br />
*mod/forum:rate - unchanged<br />
*mod/forum:viewrating - unchanged<br />
*mod/forum:viewanyrating - unchanged<br />
*mod/forum:viewallratings - cloned from old mod/forum:viewanyrating<br />
*mod/glossary:rate - unchanged<br />
*mod/glossary:viewrating - unchanged<br />
*mod/glossary:viewanyrating - cloned from old mod/glossary:viewrating<br />
*mod/glossary:viewallratings - cloned from old mod/glossary:viewrating<br />
<br />
==See also==<br />
<br />
* MDL-21657 Implement Ratings 2.0<br />
<br />
[[Category:Grades]]</div>Andyjdavishttps://docs.moodle.org/20/en/index.php?title=Development:Ratings_2.0&diff=83202Development:Ratings 2.02011-05-04T08:26:24Z<p>Andyjdavis: /* modname_rating_validate */</p>
<hr />
<div>{{Moodle 2.0}}==Objectives==<br />
<br />
Ratings are grades entered away from the gradebook. They can be entered by students and teachers and are aggregated into grades.<br />
<br />
The goals of ratings 2.0:<br />
<br />
* Manage ratings centrally<br />
* Use a consistent approach for all ratings throughout Moodle<br />
* Easily integrate ratings 2.0 with existing modules<br />
* Remove duplicate implementations of ratings functionality<br />
<br />
==Overview==<br />
<br />
The ratings 2.0 provides APIs to:<br />
# Add ratings<br />
# Update ratings<br />
# Access collected ratings for grade calculation purposes<br />
# Delete ratings<br />
<br />
==Current tracker issues==<br />
MDL-21389 Write spec for separate Ratings 2.0<br />
<br />
MDL-20514 Allow Aggregate Type in Glossary Activity<br />
<br />
MDL-21657 Implement Ratings 2.0<br />
<br />
==Interface==<br />
<br />
[[Image:RatingUI.gif]]<br />
<br />
When Javascript is enabled ajax submission means the button can be removed. In the future it would be possible to automatically interpret a 1 to 5 rating as a star rating style UI element.<br />
<br />
If the user has 'post' permission as returned by modname_rating_permissions() the dropdown box and submission button will be displayed.<br />
<br />
If the user has 'view' permissions the text to the left of the dropdown box will be displayed. The displayed text consists of the aggregate of the ratings, 4 out of 5 in the example. The number in brackets is the number of ratings that have been submitted. There have been two ratings submitted in the example.<br />
<br />
If the user has 'viewall' permissions they can click on the aggregate summary to view a list of all of the ratings that have been submitted. This is a listing of each user's profile pic, their name and the rating they submitted.<br />
<br />
<br />
==Database changes==<br />
===New tables===<br />
<br />
====Ratings====<br />
<br />
{| class="nicetable"<br />
|-<br />
! Field<br />
! Type<br />
! Default<br />
! Info<br />
|-<br />
| id<br />
| int(10)<br />
| auto-incrementing<br />
| The unique ID for this comment.<br />
|-<br />
| contextid<br />
| int(10)<br />
|<br />
| The context id defined in context table - identifies the instance of plugin owning the comment.<br />
|-<br />
| itemid<br />
| int(10)<br />
|<br />
| Some plugin specific item id (eg. forum post blog entry)<br />
|-<br />
| scaleid<br />
| int(10)<br />
|<br />
| ID of the scale (1-5, 0-100, custom) from which the user selected their rating. Including this allows smarter handling of previously entered ratings should the scales be changed.<br />
|-<br />
| rating<br />
| int(10)<br />
|<br />
| The user's rating<br />
|-<br />
| userid<br />
| int(10)<br />
|<br />
| The user who submitted the rating<br />
|-<br />
| timecreated<br />
| int(10)<br />
|<br />
| <br />
|-<br />
| timemodified<br />
| int(10)<br />
|<br />
|<br />
|}<br />
<br />
===Altered tables===<br />
The forum, glossary and data tables need to be altered to contain the required fields specificed in [https://docs.moodle.org/en/Development:Ratings_2.0#Ratings_Settings]<br />
<br />
===Removed database tables===<br />
<br />
The following tables will have their data migrated to the above ratings table and then be removed:<br />
<br />
data_ratings<br />
<br />
forum_ratings<br />
<br />
glossary_ratings<br />
<br />
===Scales===<br />
<br />
Course modules will continue to store the scale associated with their ratings. For example the glossary table has a scale column.<br />
<br />
Scales are going to be refactored as part of a separate issue. See MDL-17258.<br />
<br />
==Ratings code changes==<br />
<br />
rating/lib.php will contain...<br />
<br />
===class rating===<br />
<br />
====__construct($options)====<br />
<br />
Initialize a class instance. Requires context, itemid, scaleid and userid.<br />
<br />
====update_rating($rating)====<br />
<br />
Add or update the numerical value of the rating in the database<br />
<br />
====get_rating()====<br />
<br />
get the numerical value of the rating<br />
<br />
====delete_rating()====<br />
<br />
delete the rating. Not implemented yet as it hasn't been required.<br />
<br />
===class rating_manager===<br />
<br />
====public get_ratings($options)====<br />
Returns the supplied set of items with a rating instance attached to each item.<br />
<br />
$items is an array of objects with an id member variable ie $items[0]->id.<br />
$options requires context, items, aggregate and scaleid.<br />
<br />
items is an array of items such as forum posts or glossary items. They must have an 'id' member ie $items[0]->id.<br />
aggregate is the the aggregation method to apply. RATING_AGGREGATE_AVERAGE etc.<br />
<br />
Optionally options may include userid, returnurl, assesstimestart and assesstimefinish.<br />
<br />
If userid is omitted the current user's id will be used.<br />
returnurl is the url to return the user to after submitting a rating. Can be left null for ajax requests.<br />
assesstimestart. Only allow rating of items created after this timestamp.<br />
assesstimefinish. Only allow rating of items created before this timestamp.<br />
<br />
<code php><br />
function get_ratings($options) {<br />
global $DB, $USER;<br />
<br />
if (isnull($userid)) {<br />
$userid = $USER->id;<br />
}<br />
<br />
$itemids = array();<br />
foreach($items as $item) {<br />
$itemids[] = $item->id;<br />
}<br />
<br />
list($itemidtest, $params) = $DB->get_in_or_equal(<br />
$itemids, SQL_PARAMS_NAMED, 'itemid0000');<br />
<br />
$sql = "SELECT r.itemid, ur.id, ur.userid, ur.scaleid,<br />
$aggregatestr(r.rating) AS aggrrating,<br />
COUNT(r.rating) AS numratings,<br />
ur.rating AS usersrating<br />
FROM {ratings} r<br />
LEFT JOIN {ratings} ur ON ur.contextid = r.contextid AND<br />
ur.itemid = r.itemid AND<br />
ur.userid = :userid<br />
WHERE<br />
r.contextid = :contextid AND<br />
r.itemid $itemidtest<br />
GROUP BY r.itemid, ur.rating<br />
ORDER BY r.itemid";<br />
<br />
$params['userid'] = $userid;<br />
$params['contextid'] = $context->id;<br />
<br />
//add ratings to the items at $item->rating. Similar to make_context_subobj().<br />
//Iterate over forum $items (forum posts, glossary items etc) and create the $item->rating objects. Properties of the individual ratings, such as $item->rating->aggregate and $item->rating->rating, are stored on the rating object directly.<br />
//Settings common to the ratings are stored at $item->rating->settings->aggregationmethod (for example).<br />
}<br />
</code><br />
<br />
====get_aggregation_method($aggregate)====<br />
Converts the aggregation method constants to a string that can be included in SQL<br />
<br />
====get_all_ratings_for_item($options)====<br />
Load all ratings for a given item. Used to display a listing of submitted ratings to users with 'viewall' permission.<br />
<br />
Requires context, itemid and optionally accepts an SQL order by clause.<br />
<br />
====get_user_grades($options)====<br />
Returns a grade for a user based on other user's rating of their items.<br />
<br />
===Rendering ratings===<br />
<br />
As rendering a rating will consist of only a single function call a new method called render_rating() will be added to the core renderer.<br />
<br />
If necessary a ratings renderer could be added. Located in mod/ratings/renderer.php this new class core_rating_renderer should extend plugin_renderer_base defined in lib/outputrenderers.php Almost all renderers appear to inherit from plugin_renderer_base rather than core_renderer.<br />
<br />
=====core_renderer::render_rating(rating $rating)=====<br />
<br />
returns rating UI html snippet. Used to include ratings in pages.<br />
<br />
===Using the rating renderer===<br />
<br />
The process to render ratings is as follows:<br />
<br />
<code php><br />
// in mod/forum/discuss.php (for example)<br />
$posts = // Some forum/lib.php function call.<br />
<br />
//these are supplied by the calling module (forum etc)<br />
$aggregate = <br />
$scaleid = <br />
$userid =<br />
$returnurl = <br />
<br />
//The current scaleid comes from the forum or glossary object and may be changed at any time so supply it each time<br />
//Also, a user should only see their own ratings<br />
$posts = rating::load_ratings($context, <br />
$posts/* Optional array of items (forum posts or glossary items) with an 'id' property. If null returns all ratings for the context by the user*/, <br />
$aggregate, <br />
$scaleid, <br />
$userid, <br />
$returnurl);<br />
<br />
//ratings are now attached to the post objects. $posts[0]->rating<br />
<br />
foreach ($posts as $postid => $post) {<br />
$forumoutput->post($post);//access the rating info at $post->rating, $post->rating->aggregate and $post->rating->count<br />
}<br />
<br />
// in mod/forum/renderer.php, in the post($post) method:<br />
<br />
// ... output most of the post ... starts around line 5813 of mod/forum/lib.php<br />
echo $OUTPUT->render($item->rating);<br />
// ... output the rest.<br />
<br />
<br />
// and finally in rating/lib.php in the rating class:<br />
<br />
public function core_renderer::render_rating(rating $rating) {<br />
//return html representation of the rating<br />
}<br />
</code><br />
<br />
===Ratings Aggregation===<br />
Forums currently support multiple forms of rating aggregation such as average, maximum, sum etc. These options should be available everywhere that ratings are available.<br />
<br />
They are calculated within rating::ratings_load_ratings()<br />
<br />
===Ratings Settings===<br />
Settings for ratings are stored by the module. Each module table, for example forum, must contain the following columns.<br />
<br />
{| class="nicetable"<br />
|-<br />
! Field<br />
! Type<br />
! Default<br />
! Info<br />
|-<br />
| assessed<br />
| int(10)<br />
| <br />
| The aggregation method to apply. A value of 0 means ratings should be disabled. Currently the glossary stores an "allcanrate" flag in the assessed column. "allcanrate" will disappear in favour of proper permissions.<br />
|-<br />
| assesstimestart<br />
| int(10)<br />
|<br />
| From when can users submit ratings<br />
|-<br />
| assesstimefinish<br />
| int(10)<br />
|<br />
| When must users submit ratings by<br />
|-<br />
| scale<br />
| int(10)<br />
|<br />
| What scale to use<br />
|}<br />
<br />
The "Restrict ratings to posts with dates in this range" flag is calculated in the course/moodleforum_mod.php method moodleform::data_preprocessing() and is not stored in the database.<br />
<br />
====Settings interface====<br />
=====moodleform_mod::standard_coursemodule_elements()=====<br />
Adds elements to an instance of moodle form. The ratings elements should appear in a separate block from Common Module Settings.<br />
<br />
It will determine whether to include ratings settings by calling plugin_supports() found in lib/moodlelib.php like this...<br />
<code php><br />
if (plugin_supports('mod', $this->_modname, FEATURE_RATINGS, false)) {<br />
//include ratings elements<br />
}<br />
</code><br />
<br />
mod/%modulename%/lib.php defines a function called %modulename%_supports() that lists the elements that the module supports.<br />
<br />
FEATURE_MOD_RATINGS will have to be added to lib/moodlelib.php<br />
<br />
===Rating Submission===<br />
<br />
rating/rate.php will be the target for posted ratings. Previously each module implemented their own ratings submission. For example mod/glossary/rate.php within the glossary module.<br />
<br />
The supplied fields should consist of<br />
{| class="nicetable"<br />
|-<br />
! Field<br />
! Type<br />
! Default<br />
! Info<br />
|-<br />
| contextid<br />
| PARAM_INT<br />
|<br />
| The context id defined in context table - identifies the instance of plugin owning the comment.<br />
|-<br />
| itemid<br />
| PARAM_INT<br />
|<br />
| Some plugin specific item id (eg. forum post blog entry)<br />
|-<br />
| scaleid<br />
| PARAM_INT<br />
|<br />
| ID of the scale (1-5, 0-100, custom) from which the user selected their rating. Including this allows smarter handling of scales being changed.<br />
|-<br />
| rating<br />
| PARAM_INT<br />
|<br />
| for example, in user profile, you can comment user's description or interests, but they share the same itemid(==userid), we need comment_area to separate them<br />
|-<br />
| returnurl<br />
| PARAM_LOCALURL<br />
|<br />
| Null for ajax requests. If not null the url to which the user should be redirected after recording the rating<br />
|}<br />
<br />
The process to record a rating is as follows:<br />
<br />
<code php><br />
$permissions = forum_rating_permission();<br />
if($permissions['post']) {<br />
$rating = N; //the actual rating from the user<br />
$ratingObj = new rating($contextid, $scaleid, $userid, array($itemid));<br />
$ratingObj->set_rating($rating);<br />
//redirect to return url if supplied<br />
}<br />
<br />
//within the class rating<br />
function Rating::update_rating($rating) {<br />
$ratings = rating_system::load_ratings($scaleid, $userid, $contextid, array($itemid));<br />
if( !$ratings || sizeof($ratings)==0) {<br />
$data->contextid = $this->contextid;<br />
$data->scaleid = $this->scaleid;<br />
$data->userid = $this->userid;<br />
$data->rating = $rating;<br />
$DB->insert_record($this->table, $data);<br />
}<br />
else {<br />
$data->id = $this->id;<br />
$data->rating = $rating;<br />
$DB->update_record($this->table, $data);<br />
}<br />
<br />
}<br />
</code><br />
<br />
====Ajax submission====<br />
Ajax submission of ratings must be possible for sites with ajax enabled. ForumNG (http://moodle.org/mod/data/view.php?d=13&rid=2927) written by Sam Marshall contains an ajax implementation of the rating UI elements that may be useful to reference.<br />
<br />
Check if ajax is enabled like this...<br />
<code php><br />
if (empty($CFG->enableajax)) {<br />
//no ajax<br />
}<br />
else {<br />
//add ajax stuff<br />
}<br />
</code><br />
<br />
=== Permissions changes ===<br />
<br />
Ratings is dependent on two things: core capabilities and the result of a module callback (which may itself use module capabilities).<br />
<br />
====New ratings permissions====<br />
<br />
New system-wide ratings permissions will be added. These will be checked IN ADDITION to local permissions in existing modules.<br />
<br />
It is anticipated most new modules will just use these.<br />
<br />
The new capabilities are:<br />
<br />
moodle/rating:view - allows the user to view aggregated ratings made on their own items<br />
<br />
moodle/rating:viewany - allows the user to view aggregated ratings made on other people's items<br />
<br />
moodle/rating:viewall - allows the user to see individual ratings<br />
<br />
moodle/rating:rate - allows the user to make ratings on other people's items<br />
<br />
<br />
====Module callbacks====<br />
<br />
This allows modules to individually control ratings so, for example, the user may be able to rate forum posts but not glossary items. Modules can also control ratings through settings outside of the capabilities system. <br />
<br />
Modules do not need to implement this. It's mostly provided for backward compatibility with older modules that had complicated ratings related logic or for modules that use settings other than capabilities to control ratings behavior.<br />
<br />
=====modname_rating_permissions=====<br />
Modules can implement a function named '''modname_rating_permissions''' to control post and view permission. This is called prior to rendering a set of ratings. It is also called by rating/rate.php and rate/rate_ajax.php when they receive rating submissions.<br />
<br />
This function will return an array: array('view'=>true, 'viewany'=>true, 'viewall'=>true, 'rate'=>true)<br />
<br />
This example shows how this would work for the forum module<br />
<code php><br />
function forum_rating_permissions($context) {<br />
return array('view'=>has_capability('mod/forum:viewrating',$context), <br />
'viewany'=>has_capability('mod/forum:viewanyrating',$context), <br />
'viewall'=>has_capability('mod/forum:viewallratings',$context), <br />
'rate'=>has_capability('mod/forum:rate',$context));<br />
}<br />
</code><br />
<br />
=====modname_rating_validate=====<br />
<br />
Modules must implement a function named '''modname_rating_validate''' to verify the validity of submitted ratings.<br />
<br />
This function must return true if the rating is valid or throw an instance of rating_exception if the rating is invalid. Note: false is used to indicate that the module hasn't implemented this callback.<br />
<br />
This example shows how this would work for the forum module<br />
<code php><br />
function forum_rating_validate($params) {<br />
if (!array_key_exists('itemid', $params) || !array_key_exists('context', $params) || !array_key_exists('rateduserid', $params)) {<br />
throw new rating_exception('missingparameter');<br />
}<br />
return true;<br />
}<br />
</code><br />
<br />
The $params argument contains:<br />
* context - object the context in which the rated items exists [required]<br />
* itemid - int the ID of the object being rated<br />
* scaleid - int the scale from which the user can select a rating. Used for bounds checking. [required]<br />
* rating - int the submitted rating<br />
* rateduserid - int the id of the user whose items have been rated. NOT the user who submitted the ratings. 0 to update all. [required]<br />
* aggregation - int the aggregation method to apply when calculating grades ie RATING_AGGREGATE_AVERAGE [required]<br />
<br />
====Handling of old permissions====<br />
<br />
Pre-existing module-specific permissions will be extended to have matching names/behaviour with the new rating permissions.<br />
<br />
*mod/data:rate - unchanged<br />
*mod/data:viewrating - unchanged <br />
*mod/data:viewanyrating - cloned from old mod/data:viewrating<br />
*mod/data:viewallratings - cloned from old mod/data:viewrating<br />
*mod/forum:rate - unchanged<br />
*mod/forum:viewrating - unchanged<br />
*mod/forum:viewanyrating - unchanged<br />
*mod/forum:viewallratings - cloned from old mod/forum:viewanyrating<br />
*mod/glossary:rate - unchanged<br />
*mod/glossary:viewrating - unchanged<br />
*mod/glossary:viewanyrating - cloned from old mod/glossary:viewrating<br />
*mod/glossary:viewallratings - cloned from old mod/glossary:viewrating<br />
<br />
==See also==<br />
<br />
* MDL-21657 Implement Ratings 2.0<br />
<br />
[[Category:Grades]]</div>Andyjdavishttps://docs.moodle.org/20/en/index.php?title=Development:Ratings_2.0&diff=83201Development:Ratings 2.02011-05-04T08:26:01Z<p>Andyjdavis: /* modname_rating_validate */</p>
<hr />
<div>{{Moodle 2.0}}==Objectives==<br />
<br />
Ratings are grades entered away from the gradebook. They can be entered by students and teachers and are aggregated into grades.<br />
<br />
The goals of ratings 2.0:<br />
<br />
* Manage ratings centrally<br />
* Use a consistent approach for all ratings throughout Moodle<br />
* Easily integrate ratings 2.0 with existing modules<br />
* Remove duplicate implementations of ratings functionality<br />
<br />
==Overview==<br />
<br />
The ratings 2.0 provides APIs to:<br />
# Add ratings<br />
# Update ratings<br />
# Access collected ratings for grade calculation purposes<br />
# Delete ratings<br />
<br />
==Current tracker issues==<br />
MDL-21389 Write spec for separate Ratings 2.0<br />
<br />
MDL-20514 Allow Aggregate Type in Glossary Activity<br />
<br />
MDL-21657 Implement Ratings 2.0<br />
<br />
==Interface==<br />
<br />
[[Image:RatingUI.gif]]<br />
<br />
When Javascript is enabled ajax submission means the button can be removed. In the future it would be possible to automatically interpret a 1 to 5 rating as a star rating style UI element.<br />
<br />
If the user has 'post' permission as returned by modname_rating_permissions() the dropdown box and submission button will be displayed.<br />
<br />
If the user has 'view' permissions the text to the left of the dropdown box will be displayed. The displayed text consists of the aggregate of the ratings, 4 out of 5 in the example. The number in brackets is the number of ratings that have been submitted. There have been two ratings submitted in the example.<br />
<br />
If the user has 'viewall' permissions they can click on the aggregate summary to view a list of all of the ratings that have been submitted. This is a listing of each user's profile pic, their name and the rating they submitted.<br />
<br />
<br />
==Database changes==<br />
===New tables===<br />
<br />
====Ratings====<br />
<br />
{| class="nicetable"<br />
|-<br />
! Field<br />
! Type<br />
! Default<br />
! Info<br />
|-<br />
| id<br />
| int(10)<br />
| auto-incrementing<br />
| The unique ID for this comment.<br />
|-<br />
| contextid<br />
| int(10)<br />
|<br />
| The context id defined in context table - identifies the instance of plugin owning the comment.<br />
|-<br />
| itemid<br />
| int(10)<br />
|<br />
| Some plugin specific item id (eg. forum post blog entry)<br />
|-<br />
| scaleid<br />
| int(10)<br />
|<br />
| ID of the scale (1-5, 0-100, custom) from which the user selected their rating. Including this allows smarter handling of previously entered ratings should the scales be changed.<br />
|-<br />
| rating<br />
| int(10)<br />
|<br />
| The user's rating<br />
|-<br />
| userid<br />
| int(10)<br />
|<br />
| The user who submitted the rating<br />
|-<br />
| timecreated<br />
| int(10)<br />
|<br />
| <br />
|-<br />
| timemodified<br />
| int(10)<br />
|<br />
|<br />
|}<br />
<br />
===Altered tables===<br />
The forum, glossary and data tables need to be altered to contain the required fields specificed in [https://docs.moodle.org/en/Development:Ratings_2.0#Ratings_Settings]<br />
<br />
===Removed database tables===<br />
<br />
The following tables will have their data migrated to the above ratings table and then be removed:<br />
<br />
data_ratings<br />
<br />
forum_ratings<br />
<br />
glossary_ratings<br />
<br />
===Scales===<br />
<br />
Course modules will continue to store the scale associated with their ratings. For example the glossary table has a scale column.<br />
<br />
Scales are going to be refactored as part of a separate issue. See MDL-17258.<br />
<br />
==Ratings code changes==<br />
<br />
rating/lib.php will contain...<br />
<br />
===class rating===<br />
<br />
====__construct($options)====<br />
<br />
Initialize a class instance. Requires context, itemid, scaleid and userid.<br />
<br />
====update_rating($rating)====<br />
<br />
Add or update the numerical value of the rating in the database<br />
<br />
====get_rating()====<br />
<br />
get the numerical value of the rating<br />
<br />
====delete_rating()====<br />
<br />
delete the rating. Not implemented yet as it hasn't been required.<br />
<br />
===class rating_manager===<br />
<br />
====public get_ratings($options)====<br />
Returns the supplied set of items with a rating instance attached to each item.<br />
<br />
$items is an array of objects with an id member variable ie $items[0]->id.<br />
$options requires context, items, aggregate and scaleid.<br />
<br />
items is an array of items such as forum posts or glossary items. They must have an 'id' member ie $items[0]->id.<br />
aggregate is the the aggregation method to apply. RATING_AGGREGATE_AVERAGE etc.<br />
<br />
Optionally options may include userid, returnurl, assesstimestart and assesstimefinish.<br />
<br />
If userid is omitted the current user's id will be used.<br />
returnurl is the url to return the user to after submitting a rating. Can be left null for ajax requests.<br />
assesstimestart. Only allow rating of items created after this timestamp.<br />
assesstimefinish. Only allow rating of items created before this timestamp.<br />
<br />
<code php><br />
function get_ratings($options) {<br />
global $DB, $USER;<br />
<br />
if (isnull($userid)) {<br />
$userid = $USER->id;<br />
}<br />
<br />
$itemids = array();<br />
foreach($items as $item) {<br />
$itemids[] = $item->id;<br />
}<br />
<br />
list($itemidtest, $params) = $DB->get_in_or_equal(<br />
$itemids, SQL_PARAMS_NAMED, 'itemid0000');<br />
<br />
$sql = "SELECT r.itemid, ur.id, ur.userid, ur.scaleid,<br />
$aggregatestr(r.rating) AS aggrrating,<br />
COUNT(r.rating) AS numratings,<br />
ur.rating AS usersrating<br />
FROM {ratings} r<br />
LEFT JOIN {ratings} ur ON ur.contextid = r.contextid AND<br />
ur.itemid = r.itemid AND<br />
ur.userid = :userid<br />
WHERE<br />
r.contextid = :contextid AND<br />
r.itemid $itemidtest<br />
GROUP BY r.itemid, ur.rating<br />
ORDER BY r.itemid";<br />
<br />
$params['userid'] = $userid;<br />
$params['contextid'] = $context->id;<br />
<br />
//add ratings to the items at $item->rating. Similar to make_context_subobj().<br />
//Iterate over forum $items (forum posts, glossary items etc) and create the $item->rating objects. Properties of the individual ratings, such as $item->rating->aggregate and $item->rating->rating, are stored on the rating object directly.<br />
//Settings common to the ratings are stored at $item->rating->settings->aggregationmethod (for example).<br />
}<br />
</code><br />
<br />
====get_aggregation_method($aggregate)====<br />
Converts the aggregation method constants to a string that can be included in SQL<br />
<br />
====get_all_ratings_for_item($options)====<br />
Load all ratings for a given item. Used to display a listing of submitted ratings to users with 'viewall' permission.<br />
<br />
Requires context, itemid and optionally accepts an SQL order by clause.<br />
<br />
====get_user_grades($options)====<br />
Returns a grade for a user based on other user's rating of their items.<br />
<br />
===Rendering ratings===<br />
<br />
As rendering a rating will consist of only a single function call a new method called render_rating() will be added to the core renderer.<br />
<br />
If necessary a ratings renderer could be added. Located in mod/ratings/renderer.php this new class core_rating_renderer should extend plugin_renderer_base defined in lib/outputrenderers.php Almost all renderers appear to inherit from plugin_renderer_base rather than core_renderer.<br />
<br />
=====core_renderer::render_rating(rating $rating)=====<br />
<br />
returns rating UI html snippet. Used to include ratings in pages.<br />
<br />
===Using the rating renderer===<br />
<br />
The process to render ratings is as follows:<br />
<br />
<code php><br />
// in mod/forum/discuss.php (for example)<br />
$posts = // Some forum/lib.php function call.<br />
<br />
//these are supplied by the calling module (forum etc)<br />
$aggregate = <br />
$scaleid = <br />
$userid =<br />
$returnurl = <br />
<br />
//The current scaleid comes from the forum or glossary object and may be changed at any time so supply it each time<br />
//Also, a user should only see their own ratings<br />
$posts = rating::load_ratings($context, <br />
$posts/* Optional array of items (forum posts or glossary items) with an 'id' property. If null returns all ratings for the context by the user*/, <br />
$aggregate, <br />
$scaleid, <br />
$userid, <br />
$returnurl);<br />
<br />
//ratings are now attached to the post objects. $posts[0]->rating<br />
<br />
foreach ($posts as $postid => $post) {<br />
$forumoutput->post($post);//access the rating info at $post->rating, $post->rating->aggregate and $post->rating->count<br />
}<br />
<br />
// in mod/forum/renderer.php, in the post($post) method:<br />
<br />
// ... output most of the post ... starts around line 5813 of mod/forum/lib.php<br />
echo $OUTPUT->render($item->rating);<br />
// ... output the rest.<br />
<br />
<br />
// and finally in rating/lib.php in the rating class:<br />
<br />
public function core_renderer::render_rating(rating $rating) {<br />
//return html representation of the rating<br />
}<br />
</code><br />
<br />
===Ratings Aggregation===<br />
Forums currently support multiple forms of rating aggregation such as average, maximum, sum etc. These options should be available everywhere that ratings are available.<br />
<br />
They are calculated within rating::ratings_load_ratings()<br />
<br />
===Ratings Settings===<br />
Settings for ratings are stored by the module. Each module table, for example forum, must contain the following columns.<br />
<br />
{| class="nicetable"<br />
|-<br />
! Field<br />
! Type<br />
! Default<br />
! Info<br />
|-<br />
| assessed<br />
| int(10)<br />
| <br />
| The aggregation method to apply. A value of 0 means ratings should be disabled. Currently the glossary stores an "allcanrate" flag in the assessed column. "allcanrate" will disappear in favour of proper permissions.<br />
|-<br />
| assesstimestart<br />
| int(10)<br />
|<br />
| From when can users submit ratings<br />
|-<br />
| assesstimefinish<br />
| int(10)<br />
|<br />
| When must users submit ratings by<br />
|-<br />
| scale<br />
| int(10)<br />
|<br />
| What scale to use<br />
|}<br />
<br />
The "Restrict ratings to posts with dates in this range" flag is calculated in the course/moodleforum_mod.php method moodleform::data_preprocessing() and is not stored in the database.<br />
<br />
====Settings interface====<br />
=====moodleform_mod::standard_coursemodule_elements()=====<br />
Adds elements to an instance of moodle form. The ratings elements should appear in a separate block from Common Module Settings.<br />
<br />
It will determine whether to include ratings settings by calling plugin_supports() found in lib/moodlelib.php like this...<br />
<code php><br />
if (plugin_supports('mod', $this->_modname, FEATURE_RATINGS, false)) {<br />
//include ratings elements<br />
}<br />
</code><br />
<br />
mod/%modulename%/lib.php defines a function called %modulename%_supports() that lists the elements that the module supports.<br />
<br />
FEATURE_MOD_RATINGS will have to be added to lib/moodlelib.php<br />
<br />
===Rating Submission===<br />
<br />
rating/rate.php will be the target for posted ratings. Previously each module implemented their own ratings submission. For example mod/glossary/rate.php within the glossary module.<br />
<br />
The supplied fields should consist of<br />
{| class="nicetable"<br />
|-<br />
! Field<br />
! Type<br />
! Default<br />
! Info<br />
|-<br />
| contextid<br />
| PARAM_INT<br />
|<br />
| The context id defined in context table - identifies the instance of plugin owning the comment.<br />
|-<br />
| itemid<br />
| PARAM_INT<br />
|<br />
| Some plugin specific item id (eg. forum post blog entry)<br />
|-<br />
| scaleid<br />
| PARAM_INT<br />
|<br />
| ID of the scale (1-5, 0-100, custom) from which the user selected their rating. Including this allows smarter handling of scales being changed.<br />
|-<br />
| rating<br />
| PARAM_INT<br />
|<br />
| for example, in user profile, you can comment user's description or interests, but they share the same itemid(==userid), we need comment_area to separate them<br />
|-<br />
| returnurl<br />
| PARAM_LOCALURL<br />
|<br />
| Null for ajax requests. If not null the url to which the user should be redirected after recording the rating<br />
|}<br />
<br />
The process to record a rating is as follows:<br />
<br />
<code php><br />
$permissions = forum_rating_permission();<br />
if($permissions['post']) {<br />
$rating = N; //the actual rating from the user<br />
$ratingObj = new rating($contextid, $scaleid, $userid, array($itemid));<br />
$ratingObj->set_rating($rating);<br />
//redirect to return url if supplied<br />
}<br />
<br />
//within the class rating<br />
function Rating::update_rating($rating) {<br />
$ratings = rating_system::load_ratings($scaleid, $userid, $contextid, array($itemid));<br />
if( !$ratings || sizeof($ratings)==0) {<br />
$data->contextid = $this->contextid;<br />
$data->scaleid = $this->scaleid;<br />
$data->userid = $this->userid;<br />
$data->rating = $rating;<br />
$DB->insert_record($this->table, $data);<br />
}<br />
else {<br />
$data->id = $this->id;<br />
$data->rating = $rating;<br />
$DB->update_record($this->table, $data);<br />
}<br />
<br />
}<br />
</code><br />
<br />
====Ajax submission====<br />
Ajax submission of ratings must be possible for sites with ajax enabled. ForumNG (http://moodle.org/mod/data/view.php?d=13&rid=2927) written by Sam Marshall contains an ajax implementation of the rating UI elements that may be useful to reference.<br />
<br />
Check if ajax is enabled like this...<br />
<code php><br />
if (empty($CFG->enableajax)) {<br />
//no ajax<br />
}<br />
else {<br />
//add ajax stuff<br />
}<br />
</code><br />
<br />
=== Permissions changes ===<br />
<br />
Ratings is dependent on two things: core capabilities and the result of a module callback (which may itself use module capabilities).<br />
<br />
====New ratings permissions====<br />
<br />
New system-wide ratings permissions will be added. These will be checked IN ADDITION to local permissions in existing modules.<br />
<br />
It is anticipated most new modules will just use these.<br />
<br />
The new capabilities are:<br />
<br />
moodle/rating:view - allows the user to view aggregated ratings made on their own items<br />
<br />
moodle/rating:viewany - allows the user to view aggregated ratings made on other people's items<br />
<br />
moodle/rating:viewall - allows the user to see individual ratings<br />
<br />
moodle/rating:rate - allows the user to make ratings on other people's items<br />
<br />
<br />
====Module callbacks====<br />
<br />
This allows modules to individually control ratings so, for example, the user may be able to rate forum posts but not glossary items. Modules can also control ratings through settings outside of the capabilities system. <br />
<br />
Modules do not need to implement this. It's mostly provided for backward compatibility with older modules that had complicated ratings related logic or for modules that use settings other than capabilities to control ratings behavior.<br />
<br />
=====modname_rating_permissions=====<br />
Modules can implement a function named '''modname_rating_permissions''' to control post and view permission. This is called prior to rendering a set of ratings. It is also called by rating/rate.php and rate/rate_ajax.php when they receive rating submissions.<br />
<br />
This function will return an array: array('view'=>true, 'viewany'=>true, 'viewall'=>true, 'rate'=>true)<br />
<br />
This example shows how this would work for the forum module<br />
<code php><br />
function forum_rating_permissions($context) {<br />
return array('view'=>has_capability('mod/forum:viewrating',$context), <br />
'viewany'=>has_capability('mod/forum:viewanyrating',$context), <br />
'viewall'=>has_capability('mod/forum:viewallratings',$context), <br />
'rate'=>has_capability('mod/forum:rate',$context));<br />
}<br />
</code><br />
<br />
=====modname_rating_validate=====<br />
<br />
Modules can implement a function named '''modname_rating_validate''' to verify the validity of submitted ratings.<br />
<br />
This function must return true if the rating is valid or throw an instance of rating_exception if the rating is invalid. Note: false is used to indicate that the module hasn't implemented this callback.<br />
<br />
This example shows how this would work for the forum module<br />
<code php><br />
function forum_rating_validate($params) {<br />
if (!array_key_exists('itemid', $params) || !array_key_exists('context', $params) || !array_key_exists('rateduserid', $params)) {<br />
throw new rating_exception('missingparameter');<br />
}<br />
return true;<br />
}<br />
</code><br />
<br />
The $params argument contains:<br />
* context - object the context in which the rated items exists [required]<br />
* itemid - int the ID of the object being rated<br />
* scaleid - int the scale from which the user can select a rating. Used for bounds checking. [required]<br />
* rating - int the submitted rating<br />
* rateduserid - int the id of the user whose items have been rated. NOT the user who submitted the ratings. 0 to update all. [required]<br />
* aggregation - int the aggregation method to apply when calculating grades ie RATING_AGGREGATE_AVERAGE [required]<br />
<br />
====Handling of old permissions====<br />
<br />
Pre-existing module-specific permissions will be extended to have matching names/behaviour with the new rating permissions.<br />
<br />
*mod/data:rate - unchanged<br />
*mod/data:viewrating - unchanged <br />
*mod/data:viewanyrating - cloned from old mod/data:viewrating<br />
*mod/data:viewallratings - cloned from old mod/data:viewrating<br />
*mod/forum:rate - unchanged<br />
*mod/forum:viewrating - unchanged<br />
*mod/forum:viewanyrating - unchanged<br />
*mod/forum:viewallratings - cloned from old mod/forum:viewanyrating<br />
*mod/glossary:rate - unchanged<br />
*mod/glossary:viewrating - unchanged<br />
*mod/glossary:viewanyrating - cloned from old mod/glossary:viewrating<br />
*mod/glossary:viewallratings - cloned from old mod/glossary:viewrating<br />
<br />
==See also==<br />
<br />
* MDL-21657 Implement Ratings 2.0<br />
<br />
[[Category:Grades]]</div>Andyjdavishttps://docs.moodle.org/20/en/index.php?title=Development:Ratings_2.0&diff=83200Development:Ratings 2.02011-05-04T08:25:17Z<p>Andyjdavis: /* modname_rating_validate */</p>
<hr />
<div>{{Moodle 2.0}}==Objectives==<br />
<br />
Ratings are grades entered away from the gradebook. They can be entered by students and teachers and are aggregated into grades.<br />
<br />
The goals of ratings 2.0:<br />
<br />
* Manage ratings centrally<br />
* Use a consistent approach for all ratings throughout Moodle<br />
* Easily integrate ratings 2.0 with existing modules<br />
* Remove duplicate implementations of ratings functionality<br />
<br />
==Overview==<br />
<br />
The ratings 2.0 provides APIs to:<br />
# Add ratings<br />
# Update ratings<br />
# Access collected ratings for grade calculation purposes<br />
# Delete ratings<br />
<br />
==Current tracker issues==<br />
MDL-21389 Write spec for separate Ratings 2.0<br />
<br />
MDL-20514 Allow Aggregate Type in Glossary Activity<br />
<br />
MDL-21657 Implement Ratings 2.0<br />
<br />
==Interface==<br />
<br />
[[Image:RatingUI.gif]]<br />
<br />
When Javascript is enabled ajax submission means the button can be removed. In the future it would be possible to automatically interpret a 1 to 5 rating as a star rating style UI element.<br />
<br />
If the user has 'post' permission as returned by modname_rating_permissions() the dropdown box and submission button will be displayed.<br />
<br />
If the user has 'view' permissions the text to the left of the dropdown box will be displayed. The displayed text consists of the aggregate of the ratings, 4 out of 5 in the example. The number in brackets is the number of ratings that have been submitted. There have been two ratings submitted in the example.<br />
<br />
If the user has 'viewall' permissions they can click on the aggregate summary to view a list of all of the ratings that have been submitted. This is a listing of each user's profile pic, their name and the rating they submitted.<br />
<br />
<br />
==Database changes==<br />
===New tables===<br />
<br />
====Ratings====<br />
<br />
{| class="nicetable"<br />
|-<br />
! Field<br />
! Type<br />
! Default<br />
! Info<br />
|-<br />
| id<br />
| int(10)<br />
| auto-incrementing<br />
| The unique ID for this comment.<br />
|-<br />
| contextid<br />
| int(10)<br />
|<br />
| The context id defined in context table - identifies the instance of plugin owning the comment.<br />
|-<br />
| itemid<br />
| int(10)<br />
|<br />
| Some plugin specific item id (eg. forum post blog entry)<br />
|-<br />
| scaleid<br />
| int(10)<br />
|<br />
| ID of the scale (1-5, 0-100, custom) from which the user selected their rating. Including this allows smarter handling of previously entered ratings should the scales be changed.<br />
|-<br />
| rating<br />
| int(10)<br />
|<br />
| The user's rating<br />
|-<br />
| userid<br />
| int(10)<br />
|<br />
| The user who submitted the rating<br />
|-<br />
| timecreated<br />
| int(10)<br />
|<br />
| <br />
|-<br />
| timemodified<br />
| int(10)<br />
|<br />
|<br />
|}<br />
<br />
===Altered tables===<br />
The forum, glossary and data tables need to be altered to contain the required fields specificed in [https://docs.moodle.org/en/Development:Ratings_2.0#Ratings_Settings]<br />
<br />
===Removed database tables===<br />
<br />
The following tables will have their data migrated to the above ratings table and then be removed:<br />
<br />
data_ratings<br />
<br />
forum_ratings<br />
<br />
glossary_ratings<br />
<br />
===Scales===<br />
<br />
Course modules will continue to store the scale associated with their ratings. For example the glossary table has a scale column.<br />
<br />
Scales are going to be refactored as part of a separate issue. See MDL-17258.<br />
<br />
==Ratings code changes==<br />
<br />
rating/lib.php will contain...<br />
<br />
===class rating===<br />
<br />
====__construct($options)====<br />
<br />
Initialize a class instance. Requires context, itemid, scaleid and userid.<br />
<br />
====update_rating($rating)====<br />
<br />
Add or update the numerical value of the rating in the database<br />
<br />
====get_rating()====<br />
<br />
get the numerical value of the rating<br />
<br />
====delete_rating()====<br />
<br />
delete the rating. Not implemented yet as it hasn't been required.<br />
<br />
===class rating_manager===<br />
<br />
====public get_ratings($options)====<br />
Returns the supplied set of items with a rating instance attached to each item.<br />
<br />
$items is an array of objects with an id member variable ie $items[0]->id.<br />
$options requires context, items, aggregate and scaleid.<br />
<br />
items is an array of items such as forum posts or glossary items. They must have an 'id' member ie $items[0]->id.<br />
aggregate is the the aggregation method to apply. RATING_AGGREGATE_AVERAGE etc.<br />
<br />
Optionally options may include userid, returnurl, assesstimestart and assesstimefinish.<br />
<br />
If userid is omitted the current user's id will be used.<br />
returnurl is the url to return the user to after submitting a rating. Can be left null for ajax requests.<br />
assesstimestart. Only allow rating of items created after this timestamp.<br />
assesstimefinish. Only allow rating of items created before this timestamp.<br />
<br />
<code php><br />
function get_ratings($options) {<br />
global $DB, $USER;<br />
<br />
if (isnull($userid)) {<br />
$userid = $USER->id;<br />
}<br />
<br />
$itemids = array();<br />
foreach($items as $item) {<br />
$itemids[] = $item->id;<br />
}<br />
<br />
list($itemidtest, $params) = $DB->get_in_or_equal(<br />
$itemids, SQL_PARAMS_NAMED, 'itemid0000');<br />
<br />
$sql = "SELECT r.itemid, ur.id, ur.userid, ur.scaleid,<br />
$aggregatestr(r.rating) AS aggrrating,<br />
COUNT(r.rating) AS numratings,<br />
ur.rating AS usersrating<br />
FROM {ratings} r<br />
LEFT JOIN {ratings} ur ON ur.contextid = r.contextid AND<br />
ur.itemid = r.itemid AND<br />
ur.userid = :userid<br />
WHERE<br />
r.contextid = :contextid AND<br />
r.itemid $itemidtest<br />
GROUP BY r.itemid, ur.rating<br />
ORDER BY r.itemid";<br />
<br />
$params['userid'] = $userid;<br />
$params['contextid'] = $context->id;<br />
<br />
//add ratings to the items at $item->rating. Similar to make_context_subobj().<br />
//Iterate over forum $items (forum posts, glossary items etc) and create the $item->rating objects. Properties of the individual ratings, such as $item->rating->aggregate and $item->rating->rating, are stored on the rating object directly.<br />
//Settings common to the ratings are stored at $item->rating->settings->aggregationmethod (for example).<br />
}<br />
</code><br />
<br />
====get_aggregation_method($aggregate)====<br />
Converts the aggregation method constants to a string that can be included in SQL<br />
<br />
====get_all_ratings_for_item($options)====<br />
Load all ratings for a given item. Used to display a listing of submitted ratings to users with 'viewall' permission.<br />
<br />
Requires context, itemid and optionally accepts an SQL order by clause.<br />
<br />
====get_user_grades($options)====<br />
Returns a grade for a user based on other user's rating of their items.<br />
<br />
===Rendering ratings===<br />
<br />
As rendering a rating will consist of only a single function call a new method called render_rating() will be added to the core renderer.<br />
<br />
If necessary a ratings renderer could be added. Located in mod/ratings/renderer.php this new class core_rating_renderer should extend plugin_renderer_base defined in lib/outputrenderers.php Almost all renderers appear to inherit from plugin_renderer_base rather than core_renderer.<br />
<br />
=====core_renderer::render_rating(rating $rating)=====<br />
<br />
returns rating UI html snippet. Used to include ratings in pages.<br />
<br />
===Using the rating renderer===<br />
<br />
The process to render ratings is as follows:<br />
<br />
<code php><br />
// in mod/forum/discuss.php (for example)<br />
$posts = // Some forum/lib.php function call.<br />
<br />
//these are supplied by the calling module (forum etc)<br />
$aggregate = <br />
$scaleid = <br />
$userid =<br />
$returnurl = <br />
<br />
//The current scaleid comes from the forum or glossary object and may be changed at any time so supply it each time<br />
//Also, a user should only see their own ratings<br />
$posts = rating::load_ratings($context, <br />
$posts/* Optional array of items (forum posts or glossary items) with an 'id' property. If null returns all ratings for the context by the user*/, <br />
$aggregate, <br />
$scaleid, <br />
$userid, <br />
$returnurl);<br />
<br />
//ratings are now attached to the post objects. $posts[0]->rating<br />
<br />
foreach ($posts as $postid => $post) {<br />
$forumoutput->post($post);//access the rating info at $post->rating, $post->rating->aggregate and $post->rating->count<br />
}<br />
<br />
// in mod/forum/renderer.php, in the post($post) method:<br />
<br />
// ... output most of the post ... starts around line 5813 of mod/forum/lib.php<br />
echo $OUTPUT->render($item->rating);<br />
// ... output the rest.<br />
<br />
<br />
// and finally in rating/lib.php in the rating class:<br />
<br />
public function core_renderer::render_rating(rating $rating) {<br />
//return html representation of the rating<br />
}<br />
</code><br />
<br />
===Ratings Aggregation===<br />
Forums currently support multiple forms of rating aggregation such as average, maximum, sum etc. These options should be available everywhere that ratings are available.<br />
<br />
They are calculated within rating::ratings_load_ratings()<br />
<br />
===Ratings Settings===<br />
Settings for ratings are stored by the module. Each module table, for example forum, must contain the following columns.<br />
<br />
{| class="nicetable"<br />
|-<br />
! Field<br />
! Type<br />
! Default<br />
! Info<br />
|-<br />
| assessed<br />
| int(10)<br />
| <br />
| The aggregation method to apply. A value of 0 means ratings should be disabled. Currently the glossary stores an "allcanrate" flag in the assessed column. "allcanrate" will disappear in favour of proper permissions.<br />
|-<br />
| assesstimestart<br />
| int(10)<br />
|<br />
| From when can users submit ratings<br />
|-<br />
| assesstimefinish<br />
| int(10)<br />
|<br />
| When must users submit ratings by<br />
|-<br />
| scale<br />
| int(10)<br />
|<br />
| What scale to use<br />
|}<br />
<br />
The "Restrict ratings to posts with dates in this range" flag is calculated in the course/moodleforum_mod.php method moodleform::data_preprocessing() and is not stored in the database.<br />
<br />
====Settings interface====<br />
=====moodleform_mod::standard_coursemodule_elements()=====<br />
Adds elements to an instance of moodle form. The ratings elements should appear in a separate block from Common Module Settings.<br />
<br />
It will determine whether to include ratings settings by calling plugin_supports() found in lib/moodlelib.php like this...<br />
<code php><br />
if (plugin_supports('mod', $this->_modname, FEATURE_RATINGS, false)) {<br />
//include ratings elements<br />
}<br />
</code><br />
<br />
mod/%modulename%/lib.php defines a function called %modulename%_supports() that lists the elements that the module supports.<br />
<br />
FEATURE_MOD_RATINGS will have to be added to lib/moodlelib.php<br />
<br />
===Rating Submission===<br />
<br />
rating/rate.php will be the target for posted ratings. Previously each module implemented their own ratings submission. For example mod/glossary/rate.php within the glossary module.<br />
<br />
The supplied fields should consist of<br />
{| class="nicetable"<br />
|-<br />
! Field<br />
! Type<br />
! Default<br />
! Info<br />
|-<br />
| contextid<br />
| PARAM_INT<br />
|<br />
| The context id defined in context table - identifies the instance of plugin owning the comment.<br />
|-<br />
| itemid<br />
| PARAM_INT<br />
|<br />
| Some plugin specific item id (eg. forum post blog entry)<br />
|-<br />
| scaleid<br />
| PARAM_INT<br />
|<br />
| ID of the scale (1-5, 0-100, custom) from which the user selected their rating. Including this allows smarter handling of scales being changed.<br />
|-<br />
| rating<br />
| PARAM_INT<br />
|<br />
| for example, in user profile, you can comment user's description or interests, but they share the same itemid(==userid), we need comment_area to separate them<br />
|-<br />
| returnurl<br />
| PARAM_LOCALURL<br />
|<br />
| Null for ajax requests. If not null the url to which the user should be redirected after recording the rating<br />
|}<br />
<br />
The process to record a rating is as follows:<br />
<br />
<code php><br />
$permissions = forum_rating_permission();<br />
if($permissions['post']) {<br />
$rating = N; //the actual rating from the user<br />
$ratingObj = new rating($contextid, $scaleid, $userid, array($itemid));<br />
$ratingObj->set_rating($rating);<br />
//redirect to return url if supplied<br />
}<br />
<br />
//within the class rating<br />
function Rating::update_rating($rating) {<br />
$ratings = rating_system::load_ratings($scaleid, $userid, $contextid, array($itemid));<br />
if( !$ratings || sizeof($ratings)==0) {<br />
$data->contextid = $this->contextid;<br />
$data->scaleid = $this->scaleid;<br />
$data->userid = $this->userid;<br />
$data->rating = $rating;<br />
$DB->insert_record($this->table, $data);<br />
}<br />
else {<br />
$data->id = $this->id;<br />
$data->rating = $rating;<br />
$DB->update_record($this->table, $data);<br />
}<br />
<br />
}<br />
</code><br />
<br />
====Ajax submission====<br />
Ajax submission of ratings must be possible for sites with ajax enabled. ForumNG (http://moodle.org/mod/data/view.php?d=13&rid=2927) written by Sam Marshall contains an ajax implementation of the rating UI elements that may be useful to reference.<br />
<br />
Check if ajax is enabled like this...<br />
<code php><br />
if (empty($CFG->enableajax)) {<br />
//no ajax<br />
}<br />
else {<br />
//add ajax stuff<br />
}<br />
</code><br />
<br />
=== Permissions changes ===<br />
<br />
Ratings is dependent on two things: core capabilities and the result of a module callback (which may itself use module capabilities).<br />
<br />
====New ratings permissions====<br />
<br />
New system-wide ratings permissions will be added. These will be checked IN ADDITION to local permissions in existing modules.<br />
<br />
It is anticipated most new modules will just use these.<br />
<br />
The new capabilities are:<br />
<br />
moodle/rating:view - allows the user to view aggregated ratings made on their own items<br />
<br />
moodle/rating:viewany - allows the user to view aggregated ratings made on other people's items<br />
<br />
moodle/rating:viewall - allows the user to see individual ratings<br />
<br />
moodle/rating:rate - allows the user to make ratings on other people's items<br />
<br />
<br />
====Module callbacks====<br />
<br />
This allows modules to individually control ratings so, for example, the user may be able to rate forum posts but not glossary items. Modules can also control ratings through settings outside of the capabilities system. <br />
<br />
Modules do not need to implement this. It's mostly provided for backward compatibility with older modules that had complicated ratings related logic or for modules that use settings other than capabilities to control ratings behavior.<br />
<br />
=====modname_rating_permissions=====<br />
Modules can implement a function named '''modname_rating_permissions''' to control post and view permission. This is called prior to rendering a set of ratings. It is also called by rating/rate.php and rate/rate_ajax.php when they receive rating submissions.<br />
<br />
This function will return an array: array('view'=>true, 'viewany'=>true, 'viewall'=>true, 'rate'=>true)<br />
<br />
This example shows how this would work for the forum module<br />
<code php><br />
function forum_rating_permissions($context) {<br />
return array('view'=>has_capability('mod/forum:viewrating',$context), <br />
'viewany'=>has_capability('mod/forum:viewanyrating',$context), <br />
'viewall'=>has_capability('mod/forum:viewallratings',$context), <br />
'rate'=>has_capability('mod/forum:rate',$context));<br />
}<br />
</code><br />
<br />
=====modname_rating_validate=====<br />
<br />
Modules can implement a function named '''modname_rating_validate''' to verify the validity of submitted ratings.<br />
<br />
This function must return true if the rating is valid or throw an instance of rating_exception if the rating is invalid. Note: false is used to indicate that the module hasn't implemented this callback.<br />
<br />
This example shows how this would work for the forum module<br />
<code php><br />
function forum_rating_validate($params) {<br />
if (!array_key_exists('itemid', $params) || !array_key_exists('context', $params) || !array_key_exists('rateduserid', $params)) {<br />
throw new rating_exception('missingparameter');<br />
}<br />
return true;<br />
}<br />
<br />
The $params argument contains:<br />
* context - object the context in which the rated items exists [required]<br />
* itemid - int the ID of the object being rated<br />
* scaleid - int the scale from which the user can select a rating. Used for bounds checking. [required]<br />
* rating - int the submitted rating<br />
* rateduserid - int the id of the user whose items have been rated. NOT the user who submitted the ratings. 0 to update all. [required]<br />
* aggregation - int the aggregation method to apply when calculating grades ie RATING_AGGREGATE_AVERAGE [required]<br />
</code><br />
<br />
====Handling of old permissions====<br />
<br />
Pre-existing module-specific permissions will be extended to have matching names/behaviour with the new rating permissions.<br />
<br />
*mod/data:rate - unchanged<br />
*mod/data:viewrating - unchanged <br />
*mod/data:viewanyrating - cloned from old mod/data:viewrating<br />
*mod/data:viewallratings - cloned from old mod/data:viewrating<br />
*mod/forum:rate - unchanged<br />
*mod/forum:viewrating - unchanged<br />
*mod/forum:viewanyrating - unchanged<br />
*mod/forum:viewallratings - cloned from old mod/forum:viewanyrating<br />
*mod/glossary:rate - unchanged<br />
*mod/glossary:viewrating - unchanged<br />
*mod/glossary:viewanyrating - cloned from old mod/glossary:viewrating<br />
*mod/glossary:viewallratings - cloned from old mod/glossary:viewrating<br />
<br />
==See also==<br />
<br />
* MDL-21657 Implement Ratings 2.0<br />
<br />
[[Category:Grades]]</div>Andyjdavishttps://docs.moodle.org/20/en/index.php?title=Development:Ratings_2.0&diff=83199Development:Ratings 2.02011-05-04T08:22:56Z<p>Andyjdavis: /* Module callback */</p>
<hr />
<div>{{Moodle 2.0}}==Objectives==<br />
<br />
Ratings are grades entered away from the gradebook. They can be entered by students and teachers and are aggregated into grades.<br />
<br />
The goals of ratings 2.0:<br />
<br />
* Manage ratings centrally<br />
* Use a consistent approach for all ratings throughout Moodle<br />
* Easily integrate ratings 2.0 with existing modules<br />
* Remove duplicate implementations of ratings functionality<br />
<br />
==Overview==<br />
<br />
The ratings 2.0 provides APIs to:<br />
# Add ratings<br />
# Update ratings<br />
# Access collected ratings for grade calculation purposes<br />
# Delete ratings<br />
<br />
==Current tracker issues==<br />
MDL-21389 Write spec for separate Ratings 2.0<br />
<br />
MDL-20514 Allow Aggregate Type in Glossary Activity<br />
<br />
MDL-21657 Implement Ratings 2.0<br />
<br />
==Interface==<br />
<br />
[[Image:RatingUI.gif]]<br />
<br />
When Javascript is enabled ajax submission means the button can be removed. In the future it would be possible to automatically interpret a 1 to 5 rating as a star rating style UI element.<br />
<br />
If the user has 'post' permission as returned by modname_rating_permissions() the dropdown box and submission button will be displayed.<br />
<br />
If the user has 'view' permissions the text to the left of the dropdown box will be displayed. The displayed text consists of the aggregate of the ratings, 4 out of 5 in the example. The number in brackets is the number of ratings that have been submitted. There have been two ratings submitted in the example.<br />
<br />
If the user has 'viewall' permissions they can click on the aggregate summary to view a list of all of the ratings that have been submitted. This is a listing of each user's profile pic, their name and the rating they submitted.<br />
<br />
<br />
==Database changes==<br />
===New tables===<br />
<br />
====Ratings====<br />
<br />
{| class="nicetable"<br />
|-<br />
! Field<br />
! Type<br />
! Default<br />
! Info<br />
|-<br />
| id<br />
| int(10)<br />
| auto-incrementing<br />
| The unique ID for this comment.<br />
|-<br />
| contextid<br />
| int(10)<br />
|<br />
| The context id defined in context table - identifies the instance of plugin owning the comment.<br />
|-<br />
| itemid<br />
| int(10)<br />
|<br />
| Some plugin specific item id (eg. forum post blog entry)<br />
|-<br />
| scaleid<br />
| int(10)<br />
|<br />
| ID of the scale (1-5, 0-100, custom) from which the user selected their rating. Including this allows smarter handling of previously entered ratings should the scales be changed.<br />
|-<br />
| rating<br />
| int(10)<br />
|<br />
| The user's rating<br />
|-<br />
| userid<br />
| int(10)<br />
|<br />
| The user who submitted the rating<br />
|-<br />
| timecreated<br />
| int(10)<br />
|<br />
| <br />
|-<br />
| timemodified<br />
| int(10)<br />
|<br />
|<br />
|}<br />
<br />
===Altered tables===<br />
The forum, glossary and data tables need to be altered to contain the required fields specificed in [https://docs.moodle.org/en/Development:Ratings_2.0#Ratings_Settings]<br />
<br />
===Removed database tables===<br />
<br />
The following tables will have their data migrated to the above ratings table and then be removed:<br />
<br />
data_ratings<br />
<br />
forum_ratings<br />
<br />
glossary_ratings<br />
<br />
===Scales===<br />
<br />
Course modules will continue to store the scale associated with their ratings. For example the glossary table has a scale column.<br />
<br />
Scales are going to be refactored as part of a separate issue. See MDL-17258.<br />
<br />
==Ratings code changes==<br />
<br />
rating/lib.php will contain...<br />
<br />
===class rating===<br />
<br />
====__construct($options)====<br />
<br />
Initialize a class instance. Requires context, itemid, scaleid and userid.<br />
<br />
====update_rating($rating)====<br />
<br />
Add or update the numerical value of the rating in the database<br />
<br />
====get_rating()====<br />
<br />
get the numerical value of the rating<br />
<br />
====delete_rating()====<br />
<br />
delete the rating. Not implemented yet as it hasn't been required.<br />
<br />
===class rating_manager===<br />
<br />
====public get_ratings($options)====<br />
Returns the supplied set of items with a rating instance attached to each item.<br />
<br />
$items is an array of objects with an id member variable ie $items[0]->id.<br />
$options requires context, items, aggregate and scaleid.<br />
<br />
items is an array of items such as forum posts or glossary items. They must have an 'id' member ie $items[0]->id.<br />
aggregate is the the aggregation method to apply. RATING_AGGREGATE_AVERAGE etc.<br />
<br />
Optionally options may include userid, returnurl, assesstimestart and assesstimefinish.<br />
<br />
If userid is omitted the current user's id will be used.<br />
returnurl is the url to return the user to after submitting a rating. Can be left null for ajax requests.<br />
assesstimestart. Only allow rating of items created after this timestamp.<br />
assesstimefinish. Only allow rating of items created before this timestamp.<br />
<br />
<code php><br />
function get_ratings($options) {<br />
global $DB, $USER;<br />
<br />
if (isnull($userid)) {<br />
$userid = $USER->id;<br />
}<br />
<br />
$itemids = array();<br />
foreach($items as $item) {<br />
$itemids[] = $item->id;<br />
}<br />
<br />
list($itemidtest, $params) = $DB->get_in_or_equal(<br />
$itemids, SQL_PARAMS_NAMED, 'itemid0000');<br />
<br />
$sql = "SELECT r.itemid, ur.id, ur.userid, ur.scaleid,<br />
$aggregatestr(r.rating) AS aggrrating,<br />
COUNT(r.rating) AS numratings,<br />
ur.rating AS usersrating<br />
FROM {ratings} r<br />
LEFT JOIN {ratings} ur ON ur.contextid = r.contextid AND<br />
ur.itemid = r.itemid AND<br />
ur.userid = :userid<br />
WHERE<br />
r.contextid = :contextid AND<br />
r.itemid $itemidtest<br />
GROUP BY r.itemid, ur.rating<br />
ORDER BY r.itemid";<br />
<br />
$params['userid'] = $userid;<br />
$params['contextid'] = $context->id;<br />
<br />
//add ratings to the items at $item->rating. Similar to make_context_subobj().<br />
//Iterate over forum $items (forum posts, glossary items etc) and create the $item->rating objects. Properties of the individual ratings, such as $item->rating->aggregate and $item->rating->rating, are stored on the rating object directly.<br />
//Settings common to the ratings are stored at $item->rating->settings->aggregationmethod (for example).<br />
}<br />
</code><br />
<br />
====get_aggregation_method($aggregate)====<br />
Converts the aggregation method constants to a string that can be included in SQL<br />
<br />
====get_all_ratings_for_item($options)====<br />
Load all ratings for a given item. Used to display a listing of submitted ratings to users with 'viewall' permission.<br />
<br />
Requires context, itemid and optionally accepts an SQL order by clause.<br />
<br />
====get_user_grades($options)====<br />
Returns a grade for a user based on other user's rating of their items.<br />
<br />
===Rendering ratings===<br />
<br />
As rendering a rating will consist of only a single function call a new method called render_rating() will be added to the core renderer.<br />
<br />
If necessary a ratings renderer could be added. Located in mod/ratings/renderer.php this new class core_rating_renderer should extend plugin_renderer_base defined in lib/outputrenderers.php Almost all renderers appear to inherit from plugin_renderer_base rather than core_renderer.<br />
<br />
=====core_renderer::render_rating(rating $rating)=====<br />
<br />
returns rating UI html snippet. Used to include ratings in pages.<br />
<br />
===Using the rating renderer===<br />
<br />
The process to render ratings is as follows:<br />
<br />
<code php><br />
// in mod/forum/discuss.php (for example)<br />
$posts = // Some forum/lib.php function call.<br />
<br />
//these are supplied by the calling module (forum etc)<br />
$aggregate = <br />
$scaleid = <br />
$userid =<br />
$returnurl = <br />
<br />
//The current scaleid comes from the forum or glossary object and may be changed at any time so supply it each time<br />
//Also, a user should only see their own ratings<br />
$posts = rating::load_ratings($context, <br />
$posts/* Optional array of items (forum posts or glossary items) with an 'id' property. If null returns all ratings for the context by the user*/, <br />
$aggregate, <br />
$scaleid, <br />
$userid, <br />
$returnurl);<br />
<br />
//ratings are now attached to the post objects. $posts[0]->rating<br />
<br />
foreach ($posts as $postid => $post) {<br />
$forumoutput->post($post);//access the rating info at $post->rating, $post->rating->aggregate and $post->rating->count<br />
}<br />
<br />
// in mod/forum/renderer.php, in the post($post) method:<br />
<br />
// ... output most of the post ... starts around line 5813 of mod/forum/lib.php<br />
echo $OUTPUT->render($item->rating);<br />
// ... output the rest.<br />
<br />
<br />
// and finally in rating/lib.php in the rating class:<br />
<br />
public function core_renderer::render_rating(rating $rating) {<br />
//return html representation of the rating<br />
}<br />
</code><br />
<br />
===Ratings Aggregation===<br />
Forums currently support multiple forms of rating aggregation such as average, maximum, sum etc. These options should be available everywhere that ratings are available.<br />
<br />
They are calculated within rating::ratings_load_ratings()<br />
<br />
===Ratings Settings===<br />
Settings for ratings are stored by the module. Each module table, for example forum, must contain the following columns.<br />
<br />
{| class="nicetable"<br />
|-<br />
! Field<br />
! Type<br />
! Default<br />
! Info<br />
|-<br />
| assessed<br />
| int(10)<br />
| <br />
| The aggregation method to apply. A value of 0 means ratings should be disabled. Currently the glossary stores an "allcanrate" flag in the assessed column. "allcanrate" will disappear in favour of proper permissions.<br />
|-<br />
| assesstimestart<br />
| int(10)<br />
|<br />
| From when can users submit ratings<br />
|-<br />
| assesstimefinish<br />
| int(10)<br />
|<br />
| When must users submit ratings by<br />
|-<br />
| scale<br />
| int(10)<br />
|<br />
| What scale to use<br />
|}<br />
<br />
The "Restrict ratings to posts with dates in this range" flag is calculated in the course/moodleforum_mod.php method moodleform::data_preprocessing() and is not stored in the database.<br />
<br />
====Settings interface====<br />
=====moodleform_mod::standard_coursemodule_elements()=====<br />
Adds elements to an instance of moodle form. The ratings elements should appear in a separate block from Common Module Settings.<br />
<br />
It will determine whether to include ratings settings by calling plugin_supports() found in lib/moodlelib.php like this...<br />
<code php><br />
if (plugin_supports('mod', $this->_modname, FEATURE_RATINGS, false)) {<br />
//include ratings elements<br />
}<br />
</code><br />
<br />
mod/%modulename%/lib.php defines a function called %modulename%_supports() that lists the elements that the module supports.<br />
<br />
FEATURE_MOD_RATINGS will have to be added to lib/moodlelib.php<br />
<br />
===Rating Submission===<br />
<br />
rating/rate.php will be the target for posted ratings. Previously each module implemented their own ratings submission. For example mod/glossary/rate.php within the glossary module.<br />
<br />
The supplied fields should consist of<br />
{| class="nicetable"<br />
|-<br />
! Field<br />
! Type<br />
! Default<br />
! Info<br />
|-<br />
| contextid<br />
| PARAM_INT<br />
|<br />
| The context id defined in context table - identifies the instance of plugin owning the comment.<br />
|-<br />
| itemid<br />
| PARAM_INT<br />
|<br />
| Some plugin specific item id (eg. forum post blog entry)<br />
|-<br />
| scaleid<br />
| PARAM_INT<br />
|<br />
| ID of the scale (1-5, 0-100, custom) from which the user selected their rating. Including this allows smarter handling of scales being changed.<br />
|-<br />
| rating<br />
| PARAM_INT<br />
|<br />
| for example, in user profile, you can comment user's description or interests, but they share the same itemid(==userid), we need comment_area to separate them<br />
|-<br />
| returnurl<br />
| PARAM_LOCALURL<br />
|<br />
| Null for ajax requests. If not null the url to which the user should be redirected after recording the rating<br />
|}<br />
<br />
The process to record a rating is as follows:<br />
<br />
<code php><br />
$permissions = forum_rating_permission();<br />
if($permissions['post']) {<br />
$rating = N; //the actual rating from the user<br />
$ratingObj = new rating($contextid, $scaleid, $userid, array($itemid));<br />
$ratingObj->set_rating($rating);<br />
//redirect to return url if supplied<br />
}<br />
<br />
//within the class rating<br />
function Rating::update_rating($rating) {<br />
$ratings = rating_system::load_ratings($scaleid, $userid, $contextid, array($itemid));<br />
if( !$ratings || sizeof($ratings)==0) {<br />
$data->contextid = $this->contextid;<br />
$data->scaleid = $this->scaleid;<br />
$data->userid = $this->userid;<br />
$data->rating = $rating;<br />
$DB->insert_record($this->table, $data);<br />
}<br />
else {<br />
$data->id = $this->id;<br />
$data->rating = $rating;<br />
$DB->update_record($this->table, $data);<br />
}<br />
<br />
}<br />
</code><br />
<br />
====Ajax submission====<br />
Ajax submission of ratings must be possible for sites with ajax enabled. ForumNG (http://moodle.org/mod/data/view.php?d=13&rid=2927) written by Sam Marshall contains an ajax implementation of the rating UI elements that may be useful to reference.<br />
<br />
Check if ajax is enabled like this...<br />
<code php><br />
if (empty($CFG->enableajax)) {<br />
//no ajax<br />
}<br />
else {<br />
//add ajax stuff<br />
}<br />
</code><br />
<br />
=== Permissions changes ===<br />
<br />
Ratings is dependent on two things: core capabilities and the result of a module callback (which may itself use module capabilities).<br />
<br />
====New ratings permissions====<br />
<br />
New system-wide ratings permissions will be added. These will be checked IN ADDITION to local permissions in existing modules.<br />
<br />
It is anticipated most new modules will just use these.<br />
<br />
The new capabilities are:<br />
<br />
moodle/rating:view - allows the user to view aggregated ratings made on their own items<br />
<br />
moodle/rating:viewany - allows the user to view aggregated ratings made on other people's items<br />
<br />
moodle/rating:viewall - allows the user to see individual ratings<br />
<br />
moodle/rating:rate - allows the user to make ratings on other people's items<br />
<br />
<br />
====Module callbacks====<br />
<br />
This allows modules to individually control ratings so, for example, the user may be able to rate forum posts but not glossary items. Modules can also control ratings through settings outside of the capabilities system. <br />
<br />
Modules do not need to implement this. It's mostly provided for backward compatibility with older modules that had complicated ratings related logic or for modules that use settings other than capabilities to control ratings behavior.<br />
<br />
=====modname_rating_permissions=====<br />
Modules can implement a function named '''modname_rating_permissions''' to control post and view permission. This is called prior to rendering a set of ratings. It is also called by rating/rate.php and rate/rate_ajax.php when they receive rating submissions.<br />
<br />
This function will return an array: array('view'=>true, 'viewany'=>true, 'viewall'=>true, 'rate'=>true)<br />
<br />
This example shows how this would work for the forum module<br />
<code php><br />
function forum_rating_permissions($context) {<br />
return array('view'=>has_capability('mod/forum:viewrating',$context), <br />
'viewany'=>has_capability('mod/forum:viewanyrating',$context), <br />
'viewall'=>has_capability('mod/forum:viewallratings',$context), <br />
'rate'=>has_capability('mod/forum:rate',$context));<br />
}<br />
</code><br />
<br />
=====modname_rating_validate=====<br />
<br />
Modules can implement a function named '''modname_rating_validate''' to verify the validity of submitted ratings.<br />
<br />
This function must return true if the rating is valid or throw an instance of rating_exception if the rating is invalid. Note: false is used to indicate that the module hasn't implemented this callback.<br />
<br />
This example shows how this would work for the forum module<br />
<code php><br />
function forum_rating_validate($params) {<br />
if (!array_key_exists('itemid', $params) || !array_key_exists('context', $params) || !array_key_exists('rateduserid', $params)) {<br />
throw new rating_exception('missingparameter');<br />
}<br />
return true;<br />
}<br />
</code><br />
<br />
====Handling of old permissions====<br />
<br />
Pre-existing module-specific permissions will be extended to have matching names/behaviour with the new rating permissions.<br />
<br />
*mod/data:rate - unchanged<br />
*mod/data:viewrating - unchanged <br />
*mod/data:viewanyrating - cloned from old mod/data:viewrating<br />
*mod/data:viewallratings - cloned from old mod/data:viewrating<br />
*mod/forum:rate - unchanged<br />
*mod/forum:viewrating - unchanged<br />
*mod/forum:viewanyrating - unchanged<br />
*mod/forum:viewallratings - cloned from old mod/forum:viewanyrating<br />
*mod/glossary:rate - unchanged<br />
*mod/glossary:viewrating - unchanged<br />
*mod/glossary:viewanyrating - cloned from old mod/glossary:viewrating<br />
*mod/glossary:viewallratings - cloned from old mod/glossary:viewrating<br />
<br />
==See also==<br />
<br />
* MDL-21657 Implement Ratings 2.0<br />
<br />
[[Category:Grades]]</div>Andyjdavishttps://docs.moodle.org/20/en/index.php?title=Converting_your_MySQL_database_to_UTF8&diff=80641Converting your MySQL database to UTF82011-01-19T06:29:58Z<p>Andyjdavis: </p>
<hr />
<div>This document describes how to convert your MySQL database from the latin1 charset to UTF8. Moodle requires that your Database is now UTF8 and will not upgrade if your database is not.<br />
<br />
For more information about UTF8 have a look at the doc on [https://docs.moodle.org/en/Unicode unicode].<br />
<br />
==Why?==<br />
<br />
You may see the following error when upgrading your Moodle.<br />
<br />
''It is required that you store all your data in Unicode format (UTF-8). New installations must be performed into databases that have their default character set as Unicode. If you are upgrading, you should perform the UTF-8 migration process (see the Admin page).''<br />
<br />
<br />
Moodle requires UTF8 in order to provide better multilingual support and has done since Moodle 1.8. However the UTF8 check during install and upgrade was only been implemented in Moodle 2.0 and you may find you are unable to upgrade because your database was not set up correctly when you first installed Moodle or because you have been running Moodle since before 1.8 and haven't previously converted your database.<br />
<br />
==Converting an empty database==<br />
If you have created your database schema and are receiving the error during your initial installation your Moodle database will still be empty. You can simply run the below query in your database to resolve the issue.<br />
{code:SQL}<br />
alter database mydatabasename charset=utf8;<br />
{code}<br />
<br />
==Converting a database containing tables==<br />
If you have previously installed Moodle and are now getting the error the following process will allow you to convert your database.<br />
<br />
===Linux & Mac===<br />
<code bash><br />
mysqldump -uusername -ppassword -c -e --default-character-set=utf8 --single-transaction --skip-set-charset --add-drop-database -B dbname > dump.sql<br />
cp dump.sql dump-fixed.sql<br />
vim dump-fixed.sql<br />
:%s/DEFAULT CHARACTER SET latin1/DEFAULT CHARACTER SET utf8 COLLATE utf8_general_ci/<br />
:%s/DEFAULT CHARSET=latin1/DEFAULT CHARSET=utf8/<br />
:wq<br />
mysql -uusername -ppassword < dump-fixed.sql<br />
</code><br />
<br />
or alternatively using sed:<br />
<code bash><br />
# $1-dbusername $2-password $3-dbname<br />
mysqldump -u$1 -p$2 -c -e --default-character-set=utf8 --single-transaction --skip-set-charset --add-drop-database -B $3 > dump.sql<br />
sed 's/DEFAULT CHARACTER SET latin1/DEFAULT CHARACTER SET utf8 COLLATE utf8_general_ci/' <dump.sql | sed 's/DEFAULT CHARSET=latin1/DEFAULT CHARSET=utf8/' >dump-fixed.sql<br />
mysql -u$1 -p$2 < dump-fixed.sql<br />
</code><br />
<br />
====Explained====<br />
The following steps will guide you in creating a database dumb, editing the database dump so that the correct charset and collation are used and then restoring the new database.<br />
<br />
To start please open a new terminal and move to a temp directory.<br />
<br />
<code bash><br />
mysqldump -uusername -ppassword -c -e --default-character-set=utf8 --single-transaction --skip-set-charset --add-drop-database -B dbname > dump.sql<br />
</code><br />
<br />
The first step is of course to dump out the database and of course we will use mysqldump for this. We do however need to set several arguments in order to clean up the charsets and provide a dump that is not going to cause you any problems if you are moving this database to a different database server or find yourself having to restore on a reverted system.<br />
<br />
; username : The username to access your database.<br />
; password : The password for the above user.<br />
; -c : Complete inserts for better compatibility.<br />
; -e : Extended inserts for better performance.<br />
; --default-character-set=utf8 : To set the default character set.<br />
; --single-transaction : To reduce our workload if anything goes wrong.<br />
; --skip-set-charset : Obviously not wanted or needed as we are changing it anyway.<br />
; --add-drop-database : Required so we can restore over the top of our existing database.<br />
; -B : We use this option so that our dump will contain drop table and create table syntax (which we will change the syntax for).<br />
; dbname : The name of the database to convert.<br />
<br />
When you run this command a database dump will be generated into '''dump.sql'''<br />
<br />
<code bash><br />
cp dump.sql dump-fixed.sql<br />
</code><br />
Next step is to copy dump.sql to dump-fixed.sql.<br />
<br />
We will make the desired changes within dump-fixed.sql and we will keep dump.sql as it is as a backup just in case.<br />
<br />
<code bash><br />
vim dump-fixed.sql<br />
:%s/DEFAULT CHARACTER SET latin1/DEFAULT CHARACTER SET utf8 COLLATE utf8_general_ci/<br />
:%s/DEFAULT CHARSET=latin1/DEFAULT CHARSET=utf8/<br />
:wq<br />
</code><br />
Now we need to edit the dump and correct the incorrect charsets that have been used. I have chosen to do this with VIM however you can use any search+replace editor or program. ( I choose VIM for this only because every linux user is/should be familiar with it).<br />
<br />
First we open the file using VIM, and then run the three commands.<br />
<br />
The first command replaces all instances of ''DEFAULT CHARACTER SET latin1'' with ''DEFAULT CHARACTER SET utf8 COLLATE utf8_general_ci''. This is used to fix up the database's default charset and collation.<br />
<br />
The second command replaces all instances of ''DEFAULT CHARSET=latin1'' with ''DEFAULT CHARSET=utf8''. This converts all tables from using latin1 to using UTF8.<br />
<br />
The third command simply saves it and exits.<br />
<br />
<code bash><br />
mysql -uusername -ppassword < dump-fixed.sql<br />
</code><br />
Now that we've made the required changes we simply need to restore the database over top of the existing database. We can do this by running the above command.<br />
<br />
===Windows===<br />
Could someone who is familiar with Windows please convert the above into something that will work on Windows?<br />
There are likely several additional arguments for mysqldump you will need to specify including setting the file for output using -r to avoid newline issues.<br />
<br />
==More information==<br />
* [https://docs.moodle.org/en/Unicode Moodle docs: Unicode]<br />
<br />
[[Category:UTF-8]]<br />
[[Category:DB]]<br />
[[Category:SQL_databases]]<br />
<br />
[[fr:Convertir votre base MySQL en UTF-8]]</div>Andyjdavishttps://docs.moodle.org/20/en/index.php?title=Converting_your_MySQL_database_to_UTF8&diff=80640Converting your MySQL database to UTF82011-01-19T06:27:02Z<p>Andyjdavis: </p>
<hr />
<div>This document looks at how to convert your MySQL database from the latin1 charset to UTF8. Moodle requires that your Database is now UTF8 and will not upgrade if your database is not. Following the steps below will guide you in converting your database so that things once again work.<br />
<br />
For more information about UTF8 have a look at the doc on [https://docs.moodle.org/en/Unicode unicode].<br />
<br />
==Why?==<br />
<br />
You may see the following error when upgrading your Moodle.<br />
<br />
''It is required that you store all your data in Unicode format (UTF-8). New installations must be performed into databases that have their default character set as Unicode. If you are upgrading, you should perform the UTF-8 migration process (see the Admin page).''<br />
<br />
<br />
Moodle requires UTF8 in order to provide better multilingual support and has done since Moodle 1.8. However the UTF8 check during install and upgrade was only been implemented in Moodle 2.0 and you may find you are unable to upgrade because your database was not set up correctly when you first installed Moodle or because you have been running Moodle since before 1.8 and haven't previously converted your database.<br />
<br />
==Converting an empty database==<br />
If you have created your database schema and are receiving the error during your initial installation your Moodle database will still be empty. You can simply run the below query in your database to resolve the issue.<br />
{code:SQL}<br />
alter database mydatabasename charset=utf8;<br />
{code}<br />
<br />
==Converting a database containing tables==<br />
If you have previously installed Moodle and are now getting the error the following process will allow you to convert your database.<br />
<br />
===Linux & Mac===<br />
<code bash><br />
mysqldump -uusername -ppassword -c -e --default-character-set=utf8 --single-transaction --skip-set-charset --add-drop-database -B dbname > dump.sql<br />
cp dump.sql dump-fixed.sql<br />
vim dump-fixed.sql<br />
:%s/DEFAULT CHARACTER SET latin1/DEFAULT CHARACTER SET utf8 COLLATE utf8_general_ci/<br />
:%s/DEFAULT CHARSET=latin1/DEFAULT CHARSET=utf8/<br />
:wq<br />
mysql -uusername -ppassword < dump-fixed.sql<br />
</code><br />
<br />
or alternatively using sed:<br />
<code bash><br />
# $1-dbusername $2-password $3-dbname<br />
mysqldump -u$1 -p$2 -c -e --default-character-set=utf8 --single-transaction --skip-set-charset --add-drop-database -B $3 > dump.sql<br />
sed 's/DEFAULT CHARACTER SET latin1/DEFAULT CHARACTER SET utf8 COLLATE utf8_general_ci/' <dump.sql | sed 's/DEFAULT CHARSET=latin1/DEFAULT CHARSET=utf8/' >dump-fixed.sql<br />
mysql -u$1 -p$2 < dump-fixed.sql<br />
</code><br />
<br />
====Explained====<br />
The following steps will guide you in creating a database dumb, editing the database dump so that the correct charset and collation are used and then restoring the new database.<br />
<br />
To start please open a new terminal and move to a temp directory.<br />
<br />
<code bash><br />
mysqldump -uusername -ppassword -c -e --default-character-set=utf8 --single-transaction --skip-set-charset --add-drop-database -B dbname > dump.sql<br />
</code><br />
<br />
The first step is of course to dump out the database and of course we will use mysqldump for this. We do however need to set several arguments in order to clean up the charsets and provide a dump that is not going to cause you any problems if you are moving this database to a different database server or find yourself having to restore on a reverted system.<br />
<br />
; username : The username to access your database.<br />
; password : The password for the above user.<br />
; -c : Complete inserts for better compatibility.<br />
; -e : Extended inserts for better performance.<br />
; --default-character-set=utf8 : To set the default character set.<br />
; --single-transaction : To reduce our workload if anything goes wrong.<br />
; --skip-set-charset : Obviously not wanted or needed as we are changing it anyway.<br />
; --add-drop-database : Required so we can restore over the top of our existing database.<br />
; -B : We use this option so that our dump will contain drop table and create table syntax (which we will change the syntax for).<br />
; dbname : The name of the database to convert.<br />
<br />
When you run this command a database dump will be generated into '''dump.sql'''<br />
<br />
<code bash><br />
cp dump.sql dump-fixed.sql<br />
</code><br />
Next step is to copy dump.sql to dump-fixed.sql.<br />
<br />
We will make the desired changes within dump-fixed.sql and we will keep dump.sql as it is as a backup just in case.<br />
<br />
<code bash><br />
vim dump-fixed.sql<br />
:%s/DEFAULT CHARACTER SET latin1/DEFAULT CHARACTER SET utf8 COLLATE utf8_general_ci/<br />
:%s/DEFAULT CHARSET=latin1/DEFAULT CHARSET=utf8/<br />
:wq<br />
</code><br />
Now we need to edit the dump and correct the incorrect charsets that have been used. I have chosen to do this with VIM however you can use any search+replace editor or program. ( I choose VIM for this only because every linux user is/should be familiar with it).<br />
<br />
First we open the file using VIM, and then run the three commands.<br />
<br />
The first command replaces all instances of ''DEFAULT CHARACTER SET latin1'' with ''DEFAULT CHARACTER SET utf8 COLLATE utf8_general_ci''. This is used to fix up the database's default charset and collation.<br />
<br />
The second command replaces all instances of ''DEFAULT CHARSET=latin1'' with ''DEFAULT CHARSET=utf8''. This converts all tables from using latin1 to using UTF8.<br />
<br />
The third command simply saves it and exits.<br />
<br />
<code bash><br />
mysql -uusername -ppassword < dump-fixed.sql<br />
</code><br />
Now that we've made the required changes we simply need to restore the database over top of the existing database. We can do this by running the above command.<br />
<br />
===Windows===<br />
Could someone who is familiar with Windows please convert the above into something that will work on Windows?<br />
There are likely several additional arguments for mysqldump you will need to specify including setting the file for output using -r to avoid newline issues.<br />
<br />
==More information==<br />
* [https://docs.moodle.org/en/Unicode Moodle docs: Unicode]<br />
<br />
[[Category:UTF-8]]<br />
[[Category:DB]]<br />
[[Category:SQL_databases]]<br />
<br />
[[fr:Convertir votre base MySQL en UTF-8]]</div>Andyjdavishttps://docs.moodle.org/20/en/index.php?title=Unicode&diff=80639Unicode2011-01-19T06:18:27Z<p>Andyjdavis: </p>
<hr />
<div>==About unicode==<br />
<br />
[http://en.wikipedia.org/wiki/Unicode Unicode] is a character set that allows one to represent practically any language and many special characters used in science, math and technology. [[UTF-8]] is a specific encoding of Unicode used by many applications. Moodle uses UTF-8 encoding to be able to support different languages. Support was added in 1.6 and was made mandatory from 1.8 onwards.<br />
<br />
Prior to 1.6, Moodle did not support UTF-8 across all languages and the encoding in which the data was stored in the database depended upon the language used in a particular course.<br />
<br />
===Unicode collation===<br />
In MySQL, the database collation has to be set to unicode before the Moodle database is created. There are two different Unicode collations used: utf8_general_ci (default) and utf8_unicode_ci. The utf8_general_ci collation is slightly faster but less accurate than the utf8_unicode_ci collation in representing all the characters in languages. For this reason, Moodle tables are normally set-up using the utf8_unicode_ci collation. For a discussion of the difference between the collations see [http://dev.mysql.com/doc/refman/4.1/en/charset-unicode-sets.html the MySQL documentation].<br />
<br />
[http://www-atm.physics.ox.ac.uk/user/iwi/charmap.html Free On-line Unicode Character Map] gives you the possibility to see the different characters that are supported (or NOT!) in your browser and see which code is used if you need that. A nice feature with the characters is that you can easily enlarge the text in your browser to see them better. ([Ctrl]+[+] in Mozilla) If you are interested in Math symbols check list "22 Mathematical Operators". For Chemists looking for arrows, list "21" might be interesting.<br />
<br />
[http://www.catalysoft.com/catalog/unicode-1-1.jar Free offline java application], you must have java (ordinary, doesn't need the development environment) installed on your computer. Click on the JAR file. Chose Insert symbol, a popup with a list of categories comes, like "arrows" (but it doesn't have the group numbers).<br />
===Tex===<br />
Moodle has good support for mathematical expressions in its [[TeX filter]], but using Unicode instead can sometimes be good. In some places (e.g. [[Cloze|CLOZE]] questions) the \ characters for TeX can cause problems, whereas Unicode characters won't. A user can enlarge an expression with Unicode. Things that are displayed in a dropdown list won't display TeX but can contain Unicode math symbols.<br />
<br />
==Migrating to unicode==<br />
From Moodle 1.8 onwards, a database migration utility is no longer included. There is however a [[https://docs.moodle.org/en/Converting_your_MySQL_database_to_UTF8 manual process to migrate your database ]].<br />
<br />
From Moodle 1.6 onwards, all language packs are converted to UTF-8 and different languages may be used on the same page. Moodle 1.6 and 1.7 include a utility to [[Database migration|migrate your database]] from any encoding to UTF-8.<br />
<br />
Thus, if you wish to upgrade from 1.5 or an earlier version, ''you must first upgrade to 1.6 or 1.7'', migrate your database to UTF-8, and then upgrade to 1.8. Similarly, if you are using Moodle 1.6 or 1.7 and have not yet migrated your database, you need to do so before upgrading to 1.8. Please refer to [[Upgrading to Moodle 1.6]] for additional information.<br />
<br />
== See also ==<br />
* [[UTF-8]]<br />
* [[UTF-8 and BOM]]<br />
* [[:Category:UTF-8]]<br />
* [[Converting your MySQL database to UTF8]]<br />
<br />
[[Category:Environment]]<br />
[[Category:UTF-8]]<br />
<br />
[[fr:Unicode]]<br />
[[de:Unicode]]</div>Andyjdavishttps://docs.moodle.org/20/en/index.php?title=Development:Grades&diff=79147Development:Grades2010-12-14T08:12:18Z<p>Andyjdavis: /* Activity grade settings */</p>
<hr />
<div>{{Work in progress}}<br />
<br />
== Executive Summary ==<br />
<br />
This document primarily describes the current workings of the gradebook. For more detailed information about current gradebook development see [[Development:Gradebook_improvements]]<br />
<br />
The gradebook mechanisms must be rebuilt to:<br />
<br />
# '''Improve performance and scalability''' - All grades from throughout the system will be pushed to a central system of tables. This means reports based on grades can be generated much faster, and the gradebook has ultimate control over the content.<br />
# '''Improve flexibility''' - All aspects of the new gradebook will use simple plugin structures, namely: exports, imports and displays/reports. It is expected that the community will be very active in producing [[Development:Gradebook Report Tutorial |special-purpose reports]] analysing the basic grade data in new ways, for example, or writing plugins to transfer grades to student information systems.<br />
# '''Allow rubrics for outcomes (aka standards,competencies,goals)''' - As well as numerical grades, each grading item can consist of a number of scores made on a rubric against a standard outcome statement. These can be automatically converted to a numerical grade if desired or just shown as is.<br />
# '''Allow arbitrary columns and derived columns''' - Arbitrary columns of data can be added (either manually or via import). Columns can also be automatically filled based on formulas.<br />
# '''Implement limited public API''' - Activities may use this API to send grades/outcomes to gradebook and find out the final grades.<br />
<br />
== Glossary ==<br />
<br />
Here are some terms used in the gradebook, both in the development and the user interface. Using these terms in discussions about the gradebook will help to reduce confusion.<br />
<br />
{| class="nicetable"<br />
!Term<br />
!Definition<br />
|-<br />
|Activity<br />
|An instance of an activity module [[Category:Modules|Module]] (e.g. a single quiz, assignment etc...)<br />
|-<br />
|Calculation<br />
|A formula used to calculate grades, based (optionally) on other grade items. Not the same as [[Calculated_question_type|Calculated question types]].<br />
|-<br />
|Category<br />
|A set of Grade Items. A Category also has its own aggregated Grade which is calculated from its Grade Items. There is no limit to the level of nesting of Categories (a Category may belong to another Category). However, each Grade Item may belong to only one Category. <br />
|-<br />
|Course completion<br />
|The concept of meeting certain criteria for completing a course. In the context of the gradebook, this means a set of grades that must be reached, or a number of outcomes/competencies to complete/master.<br />
|-<br />
|Grade<br />
|A Grade is a single assessment. It may be a number or an item on a scale (possibly tied to an Outcome). Raw grade value is the numerical or scale grade from activity. Final grade is the grade reported in gradebook.<br />
|-<br />
|[[Gradebook|Gradebook]]<br />
|A central location in Moodle where students' Grades are stored and displayed. Teachers can keep track of their students' progress and organise which set of Grades their students will be able to see. Students see their own Grades.<br />
|-<br />
|Grade Item<br />
|A "column" of Grades. It can be created from a specific Activity or other module, calculated from other Grade Items, or entered manually.<br />
|-<br />
|[[Development:Grades#Locked_grades|Grade Locks]]<br />
|See linked section of this page<br />
|-<br />
|History<br />
|The gradebook has its own type of log, which keeps a History of all changes made to grades.<br />
|-<br />
|[[Development:Outcomes|Outcome]]<br />
|[[Development:Outcomes|Outcomes]] are specific descriptions of what a person is expected to be able to do or understand at the completion of an activity or course. An activity might have more than one outcome, and each may have a grade against it (usually on a scale). Other terms for Outcomes are ''Competencies'' and ''Goals''. See some [[Development:Outcomes_examples|Examples]].<br />
|-<br />
|[[Scales|Scale]]<br />
|A scale is a set of responses from which the teacher can choose one. eg Very cool, Cool, Fairly cool, Not very cool, Not cool<br />
|-<br />
|Letter Grades<br />
|Special representation of grade values similar to scales. Letters are configured in course contexts or above and are defined by lower boundary. eg A (above 90 %), B (above 80 %), C (above 70 %), D (above 50 %), F (above 0 %)<br />
<br />
|}<br />
<br />
== Database structures ==<br />
=== grade_items ===<br />
<br />
This table keeps information about gradeable items (ie columns). If an activity (eg an assignment or quiz) has multiple grade_items associated with it (eg several outcomes and numerical grade), then there will be a corresponding multiple number of rows in this table.<br />
<br />
idnumber is a tag unique inside a course identifying the grade item, useful for identifying data in exports and for referring to the grade item in calculations. It is the same as the idnumber in course_modules.<br />
<br />
<br />
{| border="1" cellpadding="2" cellspacing="0"<br />
|'''Field''' <br />
|'''Type''' <br />
|'''Default''' <br />
|'''Info''' <br />
|-<br />
|'''id''' <br />
|int(10) <br />
|<br />
|autoincrementing <br />
|-<br />
|'''courseid''' <br />
|int(10) <br />
|<br />
|The course this item is part of <br />
|-<br />
|'''categoryid''' <br />
|int(10) <br />
|<center>NULL</center> <br />
|the category group this item belongs to <br />
|-<br />
|itemname <br />
|varchar(255) <br />
|<center>NULL</center> <br />
|The name of this item (pushed in by the module or entered by user) <br />
|-<br />
|'''itemtype''' <br />
|varchar(30) <br />
|<br />
|'mod', 'blocks', 'manual', 'course', 'category' etc <br />
|-<br />
|itemmodule <br />
|varchar(30) <br />
|<center>NULL</center> <br />
|'forum', 'quiz', 'csv', etc <br />
|-<br />
|iteminstance <br />
|int(10) <br />
|<center>NULL</center> <br />
|id of the item module <br />
|-<br />
|itemnumber <br />
|int(10) <br />
|<center>NULL</center> <br />
|Can be used to distinguish multiple grades for an activity <br />
|-<br />
|iteminfo <br />
|text <br />
|<center>NULL</center> <br />
|Info and notes about this item XXX <br />
|-<br />
|'''idnumber'''<br />
|varchar(255) <br />
|<center>NULL</center> <br />
|Arbitrary idnumber provided by the module responsible (optional and course unique)<br />
|-<br />
|calculation <br />
|text<br />
|<center>NULL</center> <br />
|Spreadsheet-type formula used to process the raw grades into final grades<br />
|-<br />
|'''gradetype''' <br />
|int(4) <br />
|<center>1</center> <br />
|0 = none, 1 = value, 2 = scale, 3 = text <br />
|-<br />
|grademax <br />
|float(10,5) <br />
|<center>100</center> <br />
|What is the maximum allowable grade? <br />
|-<br />
|grademin <br />
|float(10,5) <br />
|<center>0</center> <br />
|What is the minimum allowable grade? <br />
|-<br />
|'''scaleid''' <br />
|int(10) <br />
|<center>NULL</center> <br />
|If this grade is based on a scale, which one is it? <br />
|-<br />
|'''outcomeid''' <br />
|int(10) <br />
|<center>NULL</center> <br />
|If this is outcome item, which outcome is it? <br />
|-<br />
|gradepass<br />
|float(10,5) <br />
|<center>0</center> <br />
|What grade is needed to pass? grademin <= gradepass <= grademax<br />
|-<br />
|multfactor <br />
|float(10,5) <br />
|<center>1.0</center> <br />
|Multiply all raw grades from activities by this <br />
|-<br />
|plusfactor <br />
|float(10,5) <br />
|<center>0.0</center> <br />
|Add this to all raw grades from activities by this <br />
|-<br />
|aggregationcoef <br />
|float(10,5) <br />
|<center>0.0</center> <br />
|Weight applied to all grades in this grade item during aggregation with other grade items.<br />
|-<br />
|sortorder <br />
|int(10) <br />
|<center>0</center> <br />
|Sorting order of the columns (pre-order walk of the grading tree)<br />
|-<br />
|display<br />
|int(10) <br />
|<center>0</center> <br />
|Display as real grades, percentages (in reference to the minimum and maximum grades) or letters (A, B, C etc..), or course default (0)<br />
|-<br />
|hidden <br />
|int(10) <br />
|<center>0</center> <br />
|1 is hidden, 1 is hide always, > 1 is a date to hide until (prevents viewing of all user grades) <br />
|-<br />
|'''locked'''<br />
|int(10) <br />
|<center>0</center> <br />
|0 is not locked, > 0 is a date when was item locked (no final grade or grade_item updates possible)<br />
|-<br />
|'''locktime'''<br />
|int(10) <br />
|<center>0</center> <br />
|0 no auto locking, > 0 is a date to lock grade item and final grades after automatically <br />
|-<br />
|deleted <br />
|int(10) <br />
|<center>0</center> <br />
|1 means the associated module instance has been deleted<br />
|-<br />
|'''needsupdate'''<br />
|int(10) <br />
|<center>0</center> <br />
|If this flag is set, then the whole column will be recalculated. If set in course item, some other item needs recalculation. Calculated and category items are recalculated together with any other items.<br />
|-<br />
|timecreated <br />
|int(10)<br />
|<br />
|The first time this grade_item was created<br />
|-<br />
|timemodified <br />
|int(10)<br />
|<br />
|The last time this grade_item was modified<br />
|}<br />
<br />
=== grade_categories ===<br />
<br />
This table keeps information about categories, used for grouping items. An associated grade_item will be maintained for each category to store the aggregate data.<br />
<br />
{| border="1" cellpadding="2" cellspacing="0"<br />
|'''Field''' <br />
|'''Type''' <br />
|'''Default''' <br />
|'''Info''' <br />
|-<br />
|'''id''' <br />
|int(10) <br />
|<br />
|autoincrementing <br />
|-<br />
|'''courseid''' <br />
|int(10) <br />
|<br />
|The course this grade category is part of <br />
|-<br />
|'''parent''' <br />
|int(10) <br />
|<center>NULL</center> <br />
|Parent grade_category (hierarchical)<br />
|-<br />
|depth<br />
|int(10) <br />
|<center>0</center> <br />
|How deep is this category from the highest level (1,2,3)<br />
|-<br />
|path<br />
|varchar(255) <br />
| <br />
|Shows the path as /1/2/3/ <br />
|-<br />
|fullname <br />
|varchar(255) <br />
|<br />
|The name of this grade category <br />
|-<br />
|aggregation <br />
|int(10) <br />
|<center>0</center> <br />
|A constant pointing to one of the predefined aggregation strategies (none, mean,median,sum, etc) <br />
|-<br />
|keephigh <br />
|int(10) <br />
|<center>0</center> <br />
|Keep only the X highest items <br />
|-<br />
|droplow <br />
|int(10) <br />
|<center>0</center> <br />
|Drop the X lowest items <br />
|-<br />
|aggregateonlygraded<br />
|int(1) <br />
|<center>0</center> <br />
|Aggregate only existing grades <br />
|-<br />
|aggregateoutcomes<br />
|int(1) <br />
|<center>0</center> <br />
|Aggregate otcomes together with normal items <br />
|-<br />
|aggregatesubcats<br />
|int(1) <br />
|<center>0</center> <br />
|Aggregate only items placed directly in category or all items in subcategories excluding the subcategory totals <br />
|-<br />
|timecreated<br />
|int(10) <br />
|<br />
|The first time this grade_category was created<br />
|-<br />
|timemodified <br />
|int(10) <br />
|<br />
|The last time this grade_category was modified<br />
|}<br />
<br />
=== grade_grades ===<br />
<br />
This table keeps individual grades for each user and each item. The raw grade is exactly as imported or submitted by modules. The rawgrademax/min and rawscaleid are stored here to record the values at the time the grade was stored, because teachers might change this for an activity! All the results are normalised/resampled/calculated for the finalgrade, which is relative to the max/min/scaleid values stored in the grade_item. The finalgrade field is effectively a cache and values are rebuilt whenever raw values or the grade_item changes.<br />
<br />
Note that the finalgrade for a scale-based item may be non-integer! It needs to be rounded on display.<br />
<br />
{| border="1" cellpadding="2" cellspacing="0"<br />
|'''Field''' <br />
|'''Type''' <br />
|'''Default''' <br />
|'''Info''' <br />
|-<br />
|'''id''' <br />
|int(10) <br />
|<br />
|autoincrementing <br />
|-<br />
|'''itemid''' <br />
|int(10) <br />
|<br />
|The item this grade belongs to <br />
|-<br />
|'''userid''' <br />
|int(10) <br />
|<br />
|The user who this grade is for <br />
|-<br />
|rawgrade<br />
|float(11,10) <br />
|<center>NULL</center> <br />
|The raw grade that came into the system<br />
|-<br />
|rawgrademax <br />
|float(11,10) <br />
|<center>100</center> <br />
|The maximum allowable grade when this was created <br />
|-<br />
|rawgrademin <br />
|float(11,10) <br />
|<center>0</center> <br />
|The minimum allowable grade when this was created <br />
|-<br />
|'''rawscaleid''' <br />
|int(10) <br />
|<center>NULL</center> <br />
|If this grade is based on a scale, which one was it? <br />
|-<br />
|'''usermodified'''<br />
|int(10) <br />
|<center>NULL</center> <br />
|the userid of the person who last modified the raw grade value<br />
|-<br />
|finalgrade<br />
|float(11,10) <br />
|<center>NULL</center> <br />
|The final grade (cached) after all calculations are made. Overriden grades are also stored here.<br />
|- <br />
|hidden <br />
|int(10) <br />
|<center>0</center> <br />
|0 is not hidden, 1 is hide always, > 1 is a date to hide until <br />
|-<br />
|'''locked'''<br />
|int(10) <br />
|<center>0</center> <br />
|0 is not locked, > 0 when was the grade locked<br />
|-<br />
|'''locktime'''<br />
|int(10) <br />
|<center>0</center> <br />
|0 is never, > 0 is a date to lock the final grade after automatically<br />
|-<br />
|exported <br />
|int(10) <br />
|<center>0</center> <br />
|0 is not exported, > 0 is the last exported date <br />
|-<br />
|excluded <br />
|int(10) <br />
|<center>0</center> <br />
|grade excluded from aggregation, > 0 is the last exported date <br />
|-<br />
|overridden <br />
|int(10) <br />
|<center>0</center> <br />
|0 is not overridden, > 0 is the last overridden date <br />
|-<br />
|feedback <br />
|text <br />
|<center>NULL</center> <br />
|Manual feedback from the teacher. Could be a code like 'mi'. <br />
|-<br />
|feedbackformat<br />
|int(10)<br />
|<center>0</center> <br />
|Text format for feedback<br />
|-<br />
|information <br />
|text <br />
|<center>NULL</center> <br />
|not sued yet (Further information like forum rating distribution 4/5/7/0/1 ?)<br />
|-<br />
|informationformat<br />
|int(10)<br />
|<center>0</center> <br />
|Text format for information<br />
|-<br />
|timecreated<br />
|int(10) <br />
|<br />
|temporary hack - the date of submission in activity if any, new field expected in 2.0<br />
|-<br />
|timemodified<br />
|int(10) <br />
|<br />
|temporary hack - the date of grading in activity or date of manual grading in gradebook, new field expected in 2.0<br />
|}<br />
<br />
=== grade_outcomes ===<br />
<br />
This table describes the outcomes used in the system. An outcome is a statement tied to a rubric scale from low to high, such as “Not met, Borderline, Met” (stored as 0,1 or 2). For more info about these see [[Development:Outcomes]].<br />
<br />
{| border="1" cellpadding="2" cellspacing="0"<br />
|'''Field''' <br />
|'''Type''' <br />
|'''Default''' <br />
|'''Info''' <br />
<br />
|-<br />
|'''id''' <br />
|int(10) <br />
|<br />
|autoincrementing <br />
<br />
|-<br />
|'''courseid''' <br />
|int(10) <br />
|<center>NULL</center> <br />
|Mostly these are defined site wide ie NULL <br />
<br />
|-<br />
|shortname <br />
|varchar(255) <br />
|<br />
|The short name or code for this outcome statement <br />
<br />
|-<br />
|fullname <br />
|text <br />
|<br />
|The full description of the outcome (usually 1 sentence) <br />
<br />
|-<br />
|'''scaleid''' <br />
|int(10) <br />
|<br />
|The recommended scale for this outcome. <br />
|-<br />
|description <br />
|text <br />
|<center>NULL</center> <br />
|The full description of the outcome (usually 1 sentence) <br />
|-<br />
|timecreated<br />
|int(10) <br />
|<br />
|the time this outcome was first created <br />
<br />
|-<br />
|timemodified<br />
|int(10) <br />
|<br />
|the time this outcome was last updated <br />
<br />
|-<br />
|'''usermodified'''<br />
|int(10) <br />
|<center>NULL</center> <br />
|the userid of the person who last modified this outcome<br />
|}<br />
<br />
=== grade_outcomes_courses ===<br />
An intersection table used to make standard outcomes available to courses.<br />
<br />
{| border="1" cellpadding="2" cellspacing="0"<br />
|'''Field''' <br />
|'''Type''' <br />
|'''Default''' <br />
|'''Info''' <br />
<br />
|-<br />
|'''id''' <br />
|int(10) <br />
|<br />
|autoincrementing <br />
<br />
|-<br />
|'''courseid'''<br />
|int(10)<br />
|<br />
|The id of the course being assigned the outcome<br />
<br />
|-<br />
|'''outcomeid''' <br />
|int(10) <br />
|<br />
|The id of the outcome being assigned to the course<br />
|}<br />
<br />
=== grade_import_newitem ===<br />
<br />
{| border="1" cellpadding="2" cellspacing="0"<br />
|'''Field''' <br />
|'''Type''' <br />
|'''Default''' <br />
|'''Info''' <br />
<br />
|-<br />
|'''id''' <br />
|int(10) <br />
|<br />
|autoincrementing <br />
<br />
|-<br />
|itemname<br />
|varchar(255)<br />
|<br />
|*TODO* Document<br />
<br />
|-<br />
|importcode<br />
|int(12) <br />
|<br />
|*TODO* Document <br />
|}<br />
<br />
=== grade_import_values ===<br />
<br />
{| border="1" cellpadding="2" cellspacing="0"<br />
|'''Field''' <br />
|'''Type''' <br />
|'''Default''' <br />
|'''Info''' <br />
<br />
|-<br />
|'''id''' <br />
|int(10) <br />
|<br />
|autoincrementing <br />
<br />
|-<br />
|'''itemid''' <br />
|int(10) <br />
|NULL<br />
|*TODO* Document <br />
<br />
|-<br />
|newgradeitem<br />
|int(10)<br />
|NULL<br />
|*TODO* Document<br />
<br />
|-<br />
|'''userid''' <br />
|int(10) <br />
|<br />
|*TODO* Document <br />
<br />
|-<br />
|finalgrade<br />
|float(10,5) <br />
|NULL<br />
|*TODO* Document <br />
<br />
|-<br />
|feedback<br />
|text<br />
|NULL<br />
|*TODO* Document <br />
<br />
|-<br />
|importcode<br />
|int(12) <br />
|<br />
|*TODO* Document <br />
|}<br />
<br />
=== History tables ===<br />
<br />
These table keep track of changes to most of the grade tables. Using these it should be possible to reconstruct the grades at any point in time in the past, or to audit grade changes over time. It should be quicker to use these tables for that, rather than storing this information in the main Moodle log. The following tables are set up for that purpose:<br />
<br />
#grade_categories_history<br />
#grade_grades_history<br />
#grade_items_history<br />
#grade_outcomes_history<br />
<br />
Each of them has exactly the same DB structure as their matching table (e.g. grade_categories), with 3 extra fields:<br />
<br />
<br />
<br />
{| border="1" cellpadding="2" cellspacing="0"<br />
|'''Field''' <br />
|'''Type''' <br />
|'''Default''' <br />
|'''Info''' <br />
<br />
|-<br />
|action<br />
|int(10) <br />
|0<br />
|The action that lead to the change being recorded (insert, update, delete)<br />
<br />
|-<br />
|'''oldid''' <br />
|int(10) <br />
|<br />
|The id of the record being changed or inserted (PK of the main table, not the history table) <br />
<br />
|-<br />
|source<br />
|varchar(255)<br />
|NULL<br />
|The module from which the action originated <br />
|}<br />
<br />
=== grade_letters ===<br />
<br />
{| border="1" cellpadding="2" cellspacing="0"<br />
|'''Field''' <br />
|'''Type''' <br />
|'''Default''' <br />
|'''Info''' <br />
<br />
|-<br />
|'''id''' <br />
|int(10) <br />
|<br />
|autoincrementing <br />
<br />
|-<br />
|contextid<br />
|int(10)<br />
|<br />
|What contextid does this letter apply to (from levels CONTEXT_SYSTEM, CONTEXT_COURSECAT or CONTEXT_COURSE)<br />
<br />
|-<br />
|lowerboundary<br />
|float(10,5) <br />
|<br />
|The lower boundary of the letter. Its upper boundary is the lower boundary of the next highest letter, unless there is none above, in which case it's grademax for that grade_item.<br />
<br />
|-<br />
|letter<br />
|varchar(255) <br />
|<br />
|The display value of the letter. Can be any character or string of characters (OK, A, 10% etc..) <br />
|}<br />
<br />
== Overview of module communication ==<br />
<br />
Modules usually store raw grades internally and pass them into gradebook every time they change. Gradebook may also request activities to resend the grades. <br />
<br />
The gradebook is designed to be as separate as possible from the code of activities - modules do not read grade tables or use internal gradebook API. <br />
<br />
Originally it was planned to use new events API, but in the end it was decided to use minimal API consisting of several function in lib/gradelib.php and each mod/xxx/lib.php<br />
<br />
<br />
<br />
=== Backward compatibility with Moodle 1.8 and earlier ===<br />
<br />
Function grade_grab_legacy_grades($courseid) may be used to request transfer of grades from legacy or 3rd party activities which were not yet converted to new grade API. This function is not called automatically.<br />
<br />
Modules are responsible to push existing grades into gradebook during upgrade.<br />
<br />
==API for communication with modules/blocks==<br />
<br />
Modules may use only functions from lib/gradelib.php which are marked as public. This API may be extended in later 1.9.x release. Activities should access/update only own grades.<br />
<br />
===grade_get_grades()===<br />
<br />
grade_get_grades($courseid, $itemtype, $itemmodule, $iteminstance, $userid_or_ids=0)<br />
<br />
Returns grading information for given activity - optionally with users grades. Manual, course or category items can not be queried.<br />
<br />
===grade_get_outcomes()===<br />
<br />
grade_get_outcomes($courseid, $itemtype, $itemmodule, $iteminstance,$userid=0)<br />
<br />
Returns list of outcomes used in course together with current outcomes for this user.<br />
<br />
===grade_is_locked()===<br />
<br />
grade_is_locked($courseid, $itemtype, $itemmodule, $iteminstance, $itemnumber, $userid=NULL)<br />
<br />
This function will tell a module whether a grade (or grade_item if $userid is not given) is currently locked or not. If it's locked to the current user then the module can print a nice message or prevent editing in the module. If no $userid is given, the method will always return the grade_item's locked state. If a $userid is given, the method will first check the grade_item's locked state (the column). If it is locked, the method will return true no matter the locked state of the specific grade being checked. If unlocked, it will return the locked state of the specific grade.<br />
([http://moodle.org/mod/forum/discuss.php?d=69223#p311329 info])<br />
<br />
===grade_update()===<br />
<br />
grade_update($source, $courseid, $itemtype, $itemmodule, $iteminstance, $itemnumber, $grades=NULL, $itemdetails=NULL)<br />
<br />
Submit new or update grade; update/create grade_item definition. Grade must have userid specified, rawgrade and feedback with format are optional. rawgrade NULL means 'Not graded', missing property or key means do not change existing. Only following grade item properties can be changed 'itemname', 'idnumber', 'gradetype', 'grademax', 'grademin', 'scaleid', 'multfactor', 'plusfactor', 'deleted'.<br />
<br />
===grade_update_outcomes()===<br />
<br />
grade_update_outcomes($source, $courseid, $itemtype, $itemmodule, $iteminstance, $userid, $data)<br />
<br />
Updates outcomes of a given user. Manual outcomes cannot be updated.<br />
<br />
== Private gradebook API ==<br />
Private API is used by gradebook plugins and core Moodle code, it may change in 2.0. Most of the interesting classes and functions are in lib/gradelib.php, grade/lib.php and grade/report/lib.php.<br />
<br />
The following 3 functions are all in /lib/gradelib.php<br />
<br />
===grade_regrade_final_grades()===<br />
<br />
grade_regrade_final_grades($courseid=NULL, $userid=NULL, $updated_item=NULL)<br />
<br />
Updates all grade_grades->finalgrade records for each grade_item matching the given attributes. The search is further restricted, so that only grade_items that have needs_update == true or that use calculation are retrieved and used for the update. The function returns the number of grade_items updated (NOT the same as the number of grades_grades updated!).<br />
<br />
===grade_verify_idnumber()===<br />
<br />
grade_verify_idnumber($idnumber, $grade_item = null, $cm = null, $gradeitem)<br />
<br />
Verify new value of idnumber - checks for uniqueness of new idnubmers, existing are kept intact.<br />
<br />
===remove_course_grades()===<br />
<br />
remove_course_grades($courseid, $showfeedback)<br />
<br />
Remove all grade related course data - history is kept<br />
<br />
<br />
TODO: add description of the other methods and classes + simple usage examples + querylib.php description<br />
<br />
== Dealing with multiple grades ==<br />
<br />
Modules usually produce only one grade item per activity. Optionally one or more outcomes may be attached to activities.<br />
<br />
Some activities may need to aggregate multiple ratings or attempts before sending them into the gradebook. Activities can not send variable number of items.<br />
<br />
If the gradebook receives multiple grade items from a module, then they are automatically grouped together in a unique grade category (with the same name as the module instance). See [[Development:Outcomes]] for more details.<br />
<br />
TODO: this may still be changed<br />
<br />
== Calculated grade items ==<br />
<br />
Categories or manual items maybe calculated using spreadsheet-like formulas. Formulas may reference other items from the same course only using Id numbers in double square brackets.<br />
<br />
eg: <nowiki>= MEAN([[quiz121]], [[quizend]]) + [[assignmentAXC]] + 20.0</nowiki><br />
<br />
== Regrading / updating of final grades ==<br />
<br />
TODO: describe needsupdate flag and incremental updates<br />
<br />
== Adjustment of raw grades ==<br />
Grade_item contains optional rules for adjusting the raw grade before it is cached into a final grade. These rules are processed BEFORE the calculation discussed above. Scale is never changed. Multfactor and plusfactor may be used to alter raw grades coming from activities, but it is recommended to use formulas instead.<br />
<br />
== Displaying the grades to ordinary participants ==<br />
<br />
The module takes responsibility for displaying grades within the module (to a student, say). It is recommended to use the real final grades obtained using grade_get_grades() functionBecause guidebook might force hiding, override grade, etc.<br />
<br />
For full display of grades in a whole course say, the student uses the same link as teachers use to access the gradebook. However, due to their different permissions they will only have access to specific reports. By default this is the ''User report'' report which only shows their own grades and has very few configuration options.<br />
<br />
== Locked grades ==<br />
<br />
Both whole columns and individual grades can be locked in the gradebook, via the ''locked'' field. Teachers may want to do this to prevent further changes from the modules, or from other teachers. When a grade is locked, any changes that might affect that grade are ignored. When the graded is unlocked, activities are asked to resend the latest grades.<br />
<br />
In the main GUIs the lock toggling will be achieved by clicking on a little padlock icon beside each entry or column.<br />
<br />
There is also an option to lock grade or item after some specified date.<br />
<br />
== Overridden grades ==<br />
<br />
Grades can be manually modified (overridden) in the gradebook. When this is done the entered value is always used instead of the aggregated, calculated or activity grade.<br />
<br />
Once grades have been overriden in the gradebook they become read only in the original module. The module should provide a visual indication as to why the grade cannot be modified.<br />
<br />
The need to improve how the module expresses that a grade has been overridden will be reduced by the new [https://docs.moodle.org/en/Development:Grading_interface_2.0 grading interface]<br />
<br />
== Hidden grades and categories ==<br />
<br />
Grades and categories can be hidden in the gradebook or the "categories and items" screen. When a category is hidden all the grade items within it are automatically hidden as well. When a category is un-hidden then all the grade items within it are un-hidden.<br />
<br />
The teacher always sees totals calculated from all relevant items (hidden or un-hidden)<br />
<br />
(Features below were added in 1.9.8 and 2.0)<br />
<br />
When a grade is shown its parent category will also be shown if it was hidden. MDL-21367<br />
<br />
The teacher decides what ordinary users can see in the case of totals that include hidden grades (MDL-21218, in 1.9.8 and 2.0). The user and overview report each have a setting to choose between:<br />
<br />
# Hide any totals that are dependent on a hidden item (show a hyphen there) [DEFAULT]<br />
# Display totals excluding the hidden items<br />
# Display full totals including the hidden items (may allow students to back-calculate hidden grades)<br />
<br />
== Logging ==<br />
<br />
All grading related changes maybe logged in history tables.<br />
<br />
== Security Issues ==<br />
<br />
For security an option to force SSL for the gradebook might be good.<br />
<br />
==Overall grade==<br />
<br />
Each course has exactly one course grade item. It may be used for this purpose now. Other course completion criteria will be implemented in 2.0.<br />
<br />
== Report plugins ==<br />
All the main interface of the gradebook are implemented as report plugins. Each plugin is fully responsible for page layout, there are some handy functions in grade/lib.php. They can even define their own capabilities and extra tables if the core tables are not enough, as they'll have a full /grade/report/xxxx/db directory.<br />
<br />
Each report defines one capability to allow people to see that report, so that admins have control over who can see what reports. For example, the participant interface can be a totally separate report plugin.<br />
<br />
This allows for the widest flexibility and safety in how grades are presented.<br />
<br />
=== Default teacher interface ===<br />
This interface will be what teachers see by default, and will subsume everything the current interface (in Moodle 1.8) does.<br />
<br />
Some snippets of functionality:<br />
{{Moodle 1.9}}<br />
Overall it's a grid, with participant names down one side and grade items along the top. <br />
<br />
Columns will be able to be collapsed together by grouping them into categories. Grades for categories can be calculated via various means. <br />
<br />
“Eye-cons” on the columns and checkboxes by every grade (this bit possibly controlled with a switch) allow hiding by category, by column, by individual grade.<br />
<br />
Textual notes can be added to each grade for more info. These show up to participants as well.<br />
<br />
A groups menu allows the teacher to switch between showing EACH of the groups they have access to, or ALL the groups they have access to.<br />
<br />
All grade items will link to modulepath/grade.php?id=44 which will work out what the current person should be allowed to see and either redirect them to the correct page or just show them immediately. This copes with situations like the quiz, say, where we want editing teachers to go to the detailed reports there while participants just see their own grade or whatever the quiz is set to show.<br />
<br />
User preference to SWITCH between showing raw grades, percentage grades, or both, or grade letters (A/B/C etc). <br />
<br />
Settings for grade letters not only define the transformation from percentage to grades, but also the transformation from letters to grades (in case the teacher edits some of the letter grades).<br />
<br />
Categories are shown above the headings for each column. Clicking for more info on a category will just show the category with a summary column showing total/average for just that category (PLUS the summary column for the whole course).<br />
<br />
All columns should be sortable up/down.<br />
<br />
At the bottom of each column is a row with the mean course score. If in groups mode, then add ANOTHER row with just the group mean. Add the number of grades used in brackets. eg 56% (11). When the report is paged, these means are still for the whole course/group (not the page!)<br />
<br />
{{Moodle 2.0}}<br />
<br />
Teachers can type “straight into” the grid using AJAX or fallback to forms. No popup menus for values.<br />
<br />
Later on we can support customisable shorthand codes to make data entry quick (eg type 'ab' for absent, or 'nge' for not good enough).<br />
<br />
See [http://test.moodle.com/grade/report/grader/index.php?id=2 the test site] for a live demo of this report.<br />
<br />
=== Default participant interface ===<br />
This interface will be what participants see by default:<br />
<br />
Some snippets of functionality:<br />
<br />
*Invert the grid to show one item per row, with the total/average at the bottom.<br />
*Use second/third columns to show categories.<br />
*Include ranking score in another column.<br />
*Show feedback<br />
*Show percentage<br />
*No editing functionality.<br />
<br />
See [http://test.moodle.com/grade/report/user/index.php?id=2 the test site] for a live demo of this report.<br />
<br />
=== Outcomes report ===<br />
This simple informational report displays all the outcomes used by the course, with the following information:<br />
<br />
*Outcome name<br />
*Overall average: If the outcome is used by more than one activity, this shows you the mean across all these activities in the current course<br />
*Site-wide: Yes or No: A site-wide outcome is automatically made available to all courses.<br />
*Activities: A list of links to the activities in the current course that use each outcome. One row per activity (table splits here)<br />
*Average: For each activity using the outcome, the average score is shown.<br />
*Number of grades: For each activity using the outcome, the number of grades is shown (non-graded participants are ignored)<br />
<br />
See [http://test.moodle.com/grade/report/outcomes/index.php?id=2 the test site] for a live demo of this report.<br />
<br />
=== Overview report ===<br />
Another basic report, showing a participant's course averages in each of the courses in which s/he has received grades.<br />
<br />
See [http://test.moodle.com/grade/report/overview/index.php the test site] for a live demo of this report.<br />
<br />
== Export plugins ==<br />
<br />
The API for these is extremely simple. Each export plugin should occupy a directory under /grade/export/xyz and needs to provide only an index.php file as a the primary interface. This file just accepts a 'courseid' parameter.<br />
<br />
== Import plugins ==<br />
<br />
Each import plugin should occupy a directory under /grade/import/xyz and needs to provide only an index.php file as a the primary interface. This file just accepts a 'courseid' parameter.<br />
<br />
The index.php will show an interface for further options and selections.<br />
<br />
Import plugin must validate data before starting the import operation, if some parts of import fail the user must be notified.<br />
<br />
Some sample import plugins are:<br />
<br />
===Import from CSV===<br />
<br />
Accepts an upload of (or URL to) a CSV file. Multiple options describe how to process the file, which columns to add etc. The imported grades always override current grades.<br />
<br />
===Import from XML===<br />
<br />
Accepts an upload of (or URL to) an XML file with this kind of format (from OU). <br />
<br />
<results batch="[someuniqueimportnumber]"><br />
<result><br />
<state>['new' or 'regrade']</state><br />
<assignment>[idnumber]</assignment><br />
<student>[studentid]</student><br />
<score>[score]</score><br />
</result><br />
<result><br />
<state>['new' or 'regrade']</state><br />
<assignment>[idnumber]</assignment><br />
<student>[studentid]</student><br />
<score>[score]</score><br />
</result><br />
[...]<br />
</results><br />
<br />
== Capabilities and Permissions ==<br />
<br />
* moodle/grade:view - view own grades or grades of other user if used in CONTEXT_USER<br />
<br />
* moodle/grade:viewall - view grades of all users<br />
<br />
* moodle/grade:viewhidden - see grades that are marked as hidden for the owner<br />
<br />
* moodle/grade:hide - be able to hide/unhide cells, items or categories<br />
<br />
* moodle/grade:lock - be able to lock cells, items or categories<br />
<br />
* moodle/grade:unlock - be able to unlock cells, items or categories<br />
<br />
* moodle/grade:manage - manage grade items and categories in gradebook (create, edit, lock, hide, delete, etc.)<br />
<br />
* moodle/grade:import - general import grades, requires separate permission for each plugin<br />
<br />
* moodle/grade:export - export grades, requires separate permission for each plugin<br />
<br />
* gradereport/grader:view - can view the grader report<br />
<br />
* gradeimport/csv:view - can view/use the csv import plugin<br />
<br />
* gradeexport/csv:view - can view/use the csv export plugin<br />
<br />
* moodle:site/accessallgroups<br />
<br />
== Development Tasks and Tracking ==<br />
<br />
For details of 1.9 development see [http://tracker.moodle.org/browse/MDL-9137 MDL-9137]<br />
<br />
For details of 2.0 development see [https://docs.moodle.org/en/Development:Gradebook_improvements Gradebook_imporovements] and [http://tracker.moodle.org/browse/MDL-19131 MDL-19131]<br />
<br />
==Updating module code==<br />
Module authors must implement new gradebook API and add upgrade code for migration of old grades into new gradebook. Fortunately the needed changes are not big.<br />
<br />
Steps:<br />
*add xxx_update_grades() function into mod/xxx/lib.php<br />
*add xxx_grade_item_update() function into mod/xxx/lib.php<br />
*patch xxx_update_instance(), xxx_add_instance() and xxx_delete_instance() to call xxx_grade_item_update()<br />
*patch all places of code that change grade values to call xxx_update_grades()<br />
*patch code that displays grades to students to use final grades from the gradebook<br />
<br />
There are many examples in official modules, assignment has the most advanced implementation.<br />
<br />
== Ideas for the future ==<br />
{{Moodle 2.1}}<br />
See [[Development:Gradebook_improvements]] and MDL-25423 for details of planned future enhancements<br />
<br />
*option to aggregate including/excluding hidden grades - needs db changes<br />
*option to rollback all changes during import operation if anything fails<br />
*performance improvements<br />
*conditional activities<br />
*course completion criteria<br />
*better public API for modules<br />
*better API for gradebook plugins<br />
*better state tracking in export plugins<br />
*ajax reports<br />
*specialised reports<br />
*submission and marking date tracking db changes<br />
*calculation formula improvements<br />
*historical views<br />
*individual graph of grades (time vs %). Bar graph, lineal graph. Add (or not) the maximum posible; line of 0 (=minimum), 25, 50 (=median), 75 and 100 (=max) percentils of the group<br />
<br />
== See also ==<br />
<br />
* [http://moodle.org/mod/forum/discuss.php?d=69223&mode=3 Gradebook Development ideas] forum discussion<br />
* Using Moodle [http://moodle.org/mod/forum/discuss.php?d=51107 New gradebook for Moodle] forum discussion<br />
* [[Development:Gradebook Report Tutorial]]<br />
<br />
[[Category:Developer|Grades]]<br />
[[Category:Grades]]</div>Andyjdavishttps://docs.moodle.org/20/en/index.php?title=Development:Grades&diff=79146Development:Grades2010-12-14T08:11:02Z<p>Andyjdavis: /* Overview of module communication */</p>
<hr />
<div>{{Work in progress}}<br />
<br />
== Executive Summary ==<br />
<br />
This document primarily describes the current workings of the gradebook. For more detailed information about current gradebook development see [[Development:Gradebook_improvements]]<br />
<br />
The gradebook mechanisms must be rebuilt to:<br />
<br />
# '''Improve performance and scalability''' - All grades from throughout the system will be pushed to a central system of tables. This means reports based on grades can be generated much faster, and the gradebook has ultimate control over the content.<br />
# '''Improve flexibility''' - All aspects of the new gradebook will use simple plugin structures, namely: exports, imports and displays/reports. It is expected that the community will be very active in producing [[Development:Gradebook Report Tutorial |special-purpose reports]] analysing the basic grade data in new ways, for example, or writing plugins to transfer grades to student information systems.<br />
# '''Allow rubrics for outcomes (aka standards,competencies,goals)''' - As well as numerical grades, each grading item can consist of a number of scores made on a rubric against a standard outcome statement. These can be automatically converted to a numerical grade if desired or just shown as is.<br />
# '''Allow arbitrary columns and derived columns''' - Arbitrary columns of data can be added (either manually or via import). Columns can also be automatically filled based on formulas.<br />
# '''Implement limited public API''' - Activities may use this API to send grades/outcomes to gradebook and find out the final grades.<br />
<br />
== Glossary ==<br />
<br />
Here are some terms used in the gradebook, both in the development and the user interface. Using these terms in discussions about the gradebook will help to reduce confusion.<br />
<br />
{| class="nicetable"<br />
!Term<br />
!Definition<br />
|-<br />
|Activity<br />
|An instance of an activity module [[Category:Modules|Module]] (e.g. a single quiz, assignment etc...)<br />
|-<br />
|Calculation<br />
|A formula used to calculate grades, based (optionally) on other grade items. Not the same as [[Calculated_question_type|Calculated question types]].<br />
|-<br />
|Category<br />
|A set of Grade Items. A Category also has its own aggregated Grade which is calculated from its Grade Items. There is no limit to the level of nesting of Categories (a Category may belong to another Category). However, each Grade Item may belong to only one Category. <br />
|-<br />
|Course completion<br />
|The concept of meeting certain criteria for completing a course. In the context of the gradebook, this means a set of grades that must be reached, or a number of outcomes/competencies to complete/master.<br />
|-<br />
|Grade<br />
|A Grade is a single assessment. It may be a number or an item on a scale (possibly tied to an Outcome). Raw grade value is the numerical or scale grade from activity. Final grade is the grade reported in gradebook.<br />
|-<br />
|[[Gradebook|Gradebook]]<br />
|A central location in Moodle where students' Grades are stored and displayed. Teachers can keep track of their students' progress and organise which set of Grades their students will be able to see. Students see their own Grades.<br />
|-<br />
|Grade Item<br />
|A "column" of Grades. It can be created from a specific Activity or other module, calculated from other Grade Items, or entered manually.<br />
|-<br />
|[[Development:Grades#Locked_grades|Grade Locks]]<br />
|See linked section of this page<br />
|-<br />
|History<br />
|The gradebook has its own type of log, which keeps a History of all changes made to grades.<br />
|-<br />
|[[Development:Outcomes|Outcome]]<br />
|[[Development:Outcomes|Outcomes]] are specific descriptions of what a person is expected to be able to do or understand at the completion of an activity or course. An activity might have more than one outcome, and each may have a grade against it (usually on a scale). Other terms for Outcomes are ''Competencies'' and ''Goals''. See some [[Development:Outcomes_examples|Examples]].<br />
|-<br />
|[[Scales|Scale]]<br />
|A scale is a set of responses from which the teacher can choose one. eg Very cool, Cool, Fairly cool, Not very cool, Not cool<br />
|-<br />
|Letter Grades<br />
|Special representation of grade values similar to scales. Letters are configured in course contexts or above and are defined by lower boundary. eg A (above 90 %), B (above 80 %), C (above 70 %), D (above 50 %), F (above 0 %)<br />
<br />
|}<br />
<br />
== Database structures ==<br />
=== grade_items ===<br />
<br />
This table keeps information about gradeable items (ie columns). If an activity (eg an assignment or quiz) has multiple grade_items associated with it (eg several outcomes and numerical grade), then there will be a corresponding multiple number of rows in this table.<br />
<br />
idnumber is a tag unique inside a course identifying the grade item, useful for identifying data in exports and for referring to the grade item in calculations. It is the same as the idnumber in course_modules.<br />
<br />
<br />
{| border="1" cellpadding="2" cellspacing="0"<br />
|'''Field''' <br />
|'''Type''' <br />
|'''Default''' <br />
|'''Info''' <br />
|-<br />
|'''id''' <br />
|int(10) <br />
|<br />
|autoincrementing <br />
|-<br />
|'''courseid''' <br />
|int(10) <br />
|<br />
|The course this item is part of <br />
|-<br />
|'''categoryid''' <br />
|int(10) <br />
|<center>NULL</center> <br />
|the category group this item belongs to <br />
|-<br />
|itemname <br />
|varchar(255) <br />
|<center>NULL</center> <br />
|The name of this item (pushed in by the module or entered by user) <br />
|-<br />
|'''itemtype''' <br />
|varchar(30) <br />
|<br />
|'mod', 'blocks', 'manual', 'course', 'category' etc <br />
|-<br />
|itemmodule <br />
|varchar(30) <br />
|<center>NULL</center> <br />
|'forum', 'quiz', 'csv', etc <br />
|-<br />
|iteminstance <br />
|int(10) <br />
|<center>NULL</center> <br />
|id of the item module <br />
|-<br />
|itemnumber <br />
|int(10) <br />
|<center>NULL</center> <br />
|Can be used to distinguish multiple grades for an activity <br />
|-<br />
|iteminfo <br />
|text <br />
|<center>NULL</center> <br />
|Info and notes about this item XXX <br />
|-<br />
|'''idnumber'''<br />
|varchar(255) <br />
|<center>NULL</center> <br />
|Arbitrary idnumber provided by the module responsible (optional and course unique)<br />
|-<br />
|calculation <br />
|text<br />
|<center>NULL</center> <br />
|Spreadsheet-type formula used to process the raw grades into final grades<br />
|-<br />
|'''gradetype''' <br />
|int(4) <br />
|<center>1</center> <br />
|0 = none, 1 = value, 2 = scale, 3 = text <br />
|-<br />
|grademax <br />
|float(10,5) <br />
|<center>100</center> <br />
|What is the maximum allowable grade? <br />
|-<br />
|grademin <br />
|float(10,5) <br />
|<center>0</center> <br />
|What is the minimum allowable grade? <br />
|-<br />
|'''scaleid''' <br />
|int(10) <br />
|<center>NULL</center> <br />
|If this grade is based on a scale, which one is it? <br />
|-<br />
|'''outcomeid''' <br />
|int(10) <br />
|<center>NULL</center> <br />
|If this is outcome item, which outcome is it? <br />
|-<br />
|gradepass<br />
|float(10,5) <br />
|<center>0</center> <br />
|What grade is needed to pass? grademin <= gradepass <= grademax<br />
|-<br />
|multfactor <br />
|float(10,5) <br />
|<center>1.0</center> <br />
|Multiply all raw grades from activities by this <br />
|-<br />
|plusfactor <br />
|float(10,5) <br />
|<center>0.0</center> <br />
|Add this to all raw grades from activities by this <br />
|-<br />
|aggregationcoef <br />
|float(10,5) <br />
|<center>0.0</center> <br />
|Weight applied to all grades in this grade item during aggregation with other grade items.<br />
|-<br />
|sortorder <br />
|int(10) <br />
|<center>0</center> <br />
|Sorting order of the columns (pre-order walk of the grading tree)<br />
|-<br />
|display<br />
|int(10) <br />
|<center>0</center> <br />
|Display as real grades, percentages (in reference to the minimum and maximum grades) or letters (A, B, C etc..), or course default (0)<br />
|-<br />
|hidden <br />
|int(10) <br />
|<center>0</center> <br />
|1 is hidden, 1 is hide always, > 1 is a date to hide until (prevents viewing of all user grades) <br />
|-<br />
|'''locked'''<br />
|int(10) <br />
|<center>0</center> <br />
|0 is not locked, > 0 is a date when was item locked (no final grade or grade_item updates possible)<br />
|-<br />
|'''locktime'''<br />
|int(10) <br />
|<center>0</center> <br />
|0 no auto locking, > 0 is a date to lock grade item and final grades after automatically <br />
|-<br />
|deleted <br />
|int(10) <br />
|<center>0</center> <br />
|1 means the associated module instance has been deleted<br />
|-<br />
|'''needsupdate'''<br />
|int(10) <br />
|<center>0</center> <br />
|If this flag is set, then the whole column will be recalculated. If set in course item, some other item needs recalculation. Calculated and category items are recalculated together with any other items.<br />
|-<br />
|timecreated <br />
|int(10)<br />
|<br />
|The first time this grade_item was created<br />
|-<br />
|timemodified <br />
|int(10)<br />
|<br />
|The last time this grade_item was modified<br />
|}<br />
<br />
=== grade_categories ===<br />
<br />
This table keeps information about categories, used for grouping items. An associated grade_item will be maintained for each category to store the aggregate data.<br />
<br />
{| border="1" cellpadding="2" cellspacing="0"<br />
|'''Field''' <br />
|'''Type''' <br />
|'''Default''' <br />
|'''Info''' <br />
|-<br />
|'''id''' <br />
|int(10) <br />
|<br />
|autoincrementing <br />
|-<br />
|'''courseid''' <br />
|int(10) <br />
|<br />
|The course this grade category is part of <br />
|-<br />
|'''parent''' <br />
|int(10) <br />
|<center>NULL</center> <br />
|Parent grade_category (hierarchical)<br />
|-<br />
|depth<br />
|int(10) <br />
|<center>0</center> <br />
|How deep is this category from the highest level (1,2,3)<br />
|-<br />
|path<br />
|varchar(255) <br />
| <br />
|Shows the path as /1/2/3/ <br />
|-<br />
|fullname <br />
|varchar(255) <br />
|<br />
|The name of this grade category <br />
|-<br />
|aggregation <br />
|int(10) <br />
|<center>0</center> <br />
|A constant pointing to one of the predefined aggregation strategies (none, mean,median,sum, etc) <br />
|-<br />
|keephigh <br />
|int(10) <br />
|<center>0</center> <br />
|Keep only the X highest items <br />
|-<br />
|droplow <br />
|int(10) <br />
|<center>0</center> <br />
|Drop the X lowest items <br />
|-<br />
|aggregateonlygraded<br />
|int(1) <br />
|<center>0</center> <br />
|Aggregate only existing grades <br />
|-<br />
|aggregateoutcomes<br />
|int(1) <br />
|<center>0</center> <br />
|Aggregate otcomes together with normal items <br />
|-<br />
|aggregatesubcats<br />
|int(1) <br />
|<center>0</center> <br />
|Aggregate only items placed directly in category or all items in subcategories excluding the subcategory totals <br />
|-<br />
|timecreated<br />
|int(10) <br />
|<br />
|The first time this grade_category was created<br />
|-<br />
|timemodified <br />
|int(10) <br />
|<br />
|The last time this grade_category was modified<br />
|}<br />
<br />
=== grade_grades ===<br />
<br />
This table keeps individual grades for each user and each item. The raw grade is exactly as imported or submitted by modules. The rawgrademax/min and rawscaleid are stored here to record the values at the time the grade was stored, because teachers might change this for an activity! All the results are normalised/resampled/calculated for the finalgrade, which is relative to the max/min/scaleid values stored in the grade_item. The finalgrade field is effectively a cache and values are rebuilt whenever raw values or the grade_item changes.<br />
<br />
Note that the finalgrade for a scale-based item may be non-integer! It needs to be rounded on display.<br />
<br />
{| border="1" cellpadding="2" cellspacing="0"<br />
|'''Field''' <br />
|'''Type''' <br />
|'''Default''' <br />
|'''Info''' <br />
|-<br />
|'''id''' <br />
|int(10) <br />
|<br />
|autoincrementing <br />
|-<br />
|'''itemid''' <br />
|int(10) <br />
|<br />
|The item this grade belongs to <br />
|-<br />
|'''userid''' <br />
|int(10) <br />
|<br />
|The user who this grade is for <br />
|-<br />
|rawgrade<br />
|float(11,10) <br />
|<center>NULL</center> <br />
|The raw grade that came into the system<br />
|-<br />
|rawgrademax <br />
|float(11,10) <br />
|<center>100</center> <br />
|The maximum allowable grade when this was created <br />
|-<br />
|rawgrademin <br />
|float(11,10) <br />
|<center>0</center> <br />
|The minimum allowable grade when this was created <br />
|-<br />
|'''rawscaleid''' <br />
|int(10) <br />
|<center>NULL</center> <br />
|If this grade is based on a scale, which one was it? <br />
|-<br />
|'''usermodified'''<br />
|int(10) <br />
|<center>NULL</center> <br />
|the userid of the person who last modified the raw grade value<br />
|-<br />
|finalgrade<br />
|float(11,10) <br />
|<center>NULL</center> <br />
|The final grade (cached) after all calculations are made. Overriden grades are also stored here.<br />
|- <br />
|hidden <br />
|int(10) <br />
|<center>0</center> <br />
|0 is not hidden, 1 is hide always, > 1 is a date to hide until <br />
|-<br />
|'''locked'''<br />
|int(10) <br />
|<center>0</center> <br />
|0 is not locked, > 0 when was the grade locked<br />
|-<br />
|'''locktime'''<br />
|int(10) <br />
|<center>0</center> <br />
|0 is never, > 0 is a date to lock the final grade after automatically<br />
|-<br />
|exported <br />
|int(10) <br />
|<center>0</center> <br />
|0 is not exported, > 0 is the last exported date <br />
|-<br />
|excluded <br />
|int(10) <br />
|<center>0</center> <br />
|grade excluded from aggregation, > 0 is the last exported date <br />
|-<br />
|overridden <br />
|int(10) <br />
|<center>0</center> <br />
|0 is not overridden, > 0 is the last overridden date <br />
|-<br />
|feedback <br />
|text <br />
|<center>NULL</center> <br />
|Manual feedback from the teacher. Could be a code like 'mi'. <br />
|-<br />
|feedbackformat<br />
|int(10)<br />
|<center>0</center> <br />
|Text format for feedback<br />
|-<br />
|information <br />
|text <br />
|<center>NULL</center> <br />
|not sued yet (Further information like forum rating distribution 4/5/7/0/1 ?)<br />
|-<br />
|informationformat<br />
|int(10)<br />
|<center>0</center> <br />
|Text format for information<br />
|-<br />
|timecreated<br />
|int(10) <br />
|<br />
|temporary hack - the date of submission in activity if any, new field expected in 2.0<br />
|-<br />
|timemodified<br />
|int(10) <br />
|<br />
|temporary hack - the date of grading in activity or date of manual grading in gradebook, new field expected in 2.0<br />
|}<br />
<br />
=== grade_outcomes ===<br />
<br />
This table describes the outcomes used in the system. An outcome is a statement tied to a rubric scale from low to high, such as “Not met, Borderline, Met” (stored as 0,1 or 2). For more info about these see [[Development:Outcomes]].<br />
<br />
{| border="1" cellpadding="2" cellspacing="0"<br />
|'''Field''' <br />
|'''Type''' <br />
|'''Default''' <br />
|'''Info''' <br />
<br />
|-<br />
|'''id''' <br />
|int(10) <br />
|<br />
|autoincrementing <br />
<br />
|-<br />
|'''courseid''' <br />
|int(10) <br />
|<center>NULL</center> <br />
|Mostly these are defined site wide ie NULL <br />
<br />
|-<br />
|shortname <br />
|varchar(255) <br />
|<br />
|The short name or code for this outcome statement <br />
<br />
|-<br />
|fullname <br />
|text <br />
|<br />
|The full description of the outcome (usually 1 sentence) <br />
<br />
|-<br />
|'''scaleid''' <br />
|int(10) <br />
|<br />
|The recommended scale for this outcome. <br />
|-<br />
|description <br />
|text <br />
|<center>NULL</center> <br />
|The full description of the outcome (usually 1 sentence) <br />
|-<br />
|timecreated<br />
|int(10) <br />
|<br />
|the time this outcome was first created <br />
<br />
|-<br />
|timemodified<br />
|int(10) <br />
|<br />
|the time this outcome was last updated <br />
<br />
|-<br />
|'''usermodified'''<br />
|int(10) <br />
|<center>NULL</center> <br />
|the userid of the person who last modified this outcome<br />
|}<br />
<br />
=== grade_outcomes_courses ===<br />
An intersection table used to make standard outcomes available to courses.<br />
<br />
{| border="1" cellpadding="2" cellspacing="0"<br />
|'''Field''' <br />
|'''Type''' <br />
|'''Default''' <br />
|'''Info''' <br />
<br />
|-<br />
|'''id''' <br />
|int(10) <br />
|<br />
|autoincrementing <br />
<br />
|-<br />
|'''courseid'''<br />
|int(10)<br />
|<br />
|The id of the course being assigned the outcome<br />
<br />
|-<br />
|'''outcomeid''' <br />
|int(10) <br />
|<br />
|The id of the outcome being assigned to the course<br />
|}<br />
<br />
=== grade_import_newitem ===<br />
<br />
{| border="1" cellpadding="2" cellspacing="0"<br />
|'''Field''' <br />
|'''Type''' <br />
|'''Default''' <br />
|'''Info''' <br />
<br />
|-<br />
|'''id''' <br />
|int(10) <br />
|<br />
|autoincrementing <br />
<br />
|-<br />
|itemname<br />
|varchar(255)<br />
|<br />
|*TODO* Document<br />
<br />
|-<br />
|importcode<br />
|int(12) <br />
|<br />
|*TODO* Document <br />
|}<br />
<br />
=== grade_import_values ===<br />
<br />
{| border="1" cellpadding="2" cellspacing="0"<br />
|'''Field''' <br />
|'''Type''' <br />
|'''Default''' <br />
|'''Info''' <br />
<br />
|-<br />
|'''id''' <br />
|int(10) <br />
|<br />
|autoincrementing <br />
<br />
|-<br />
|'''itemid''' <br />
|int(10) <br />
|NULL<br />
|*TODO* Document <br />
<br />
|-<br />
|newgradeitem<br />
|int(10)<br />
|NULL<br />
|*TODO* Document<br />
<br />
|-<br />
|'''userid''' <br />
|int(10) <br />
|<br />
|*TODO* Document <br />
<br />
|-<br />
|finalgrade<br />
|float(10,5) <br />
|NULL<br />
|*TODO* Document <br />
<br />
|-<br />
|feedback<br />
|text<br />
|NULL<br />
|*TODO* Document <br />
<br />
|-<br />
|importcode<br />
|int(12) <br />
|<br />
|*TODO* Document <br />
|}<br />
<br />
=== History tables ===<br />
<br />
These table keep track of changes to most of the grade tables. Using these it should be possible to reconstruct the grades at any point in time in the past, or to audit grade changes over time. It should be quicker to use these tables for that, rather than storing this information in the main Moodle log. The following tables are set up for that purpose:<br />
<br />
#grade_categories_history<br />
#grade_grades_history<br />
#grade_items_history<br />
#grade_outcomes_history<br />
<br />
Each of them has exactly the same DB structure as their matching table (e.g. grade_categories), with 3 extra fields:<br />
<br />
<br />
<br />
{| border="1" cellpadding="2" cellspacing="0"<br />
|'''Field''' <br />
|'''Type''' <br />
|'''Default''' <br />
|'''Info''' <br />
<br />
|-<br />
|action<br />
|int(10) <br />
|0<br />
|The action that lead to the change being recorded (insert, update, delete)<br />
<br />
|-<br />
|'''oldid''' <br />
|int(10) <br />
|<br />
|The id of the record being changed or inserted (PK of the main table, not the history table) <br />
<br />
|-<br />
|source<br />
|varchar(255)<br />
|NULL<br />
|The module from which the action originated <br />
|}<br />
<br />
=== grade_letters ===<br />
<br />
{| border="1" cellpadding="2" cellspacing="0"<br />
|'''Field''' <br />
|'''Type''' <br />
|'''Default''' <br />
|'''Info''' <br />
<br />
|-<br />
|'''id''' <br />
|int(10) <br />
|<br />
|autoincrementing <br />
<br />
|-<br />
|contextid<br />
|int(10)<br />
|<br />
|What contextid does this letter apply to (from levels CONTEXT_SYSTEM, CONTEXT_COURSECAT or CONTEXT_COURSE)<br />
<br />
|-<br />
|lowerboundary<br />
|float(10,5) <br />
|<br />
|The lower boundary of the letter. Its upper boundary is the lower boundary of the next highest letter, unless there is none above, in which case it's grademax for that grade_item.<br />
<br />
|-<br />
|letter<br />
|varchar(255) <br />
|<br />
|The display value of the letter. Can be any character or string of characters (OK, A, 10% etc..) <br />
|}<br />
<br />
== Overview of module communication ==<br />
<br />
Modules usually store raw grades internally and pass them into gradebook every time they change. Gradebook may also request activities to resend the grades. <br />
<br />
The gradebook is designed to be as separate as possible from the code of activities - modules do not read grade tables or use internal gradebook API. <br />
<br />
Originally it was planned to use new events API, but in the end it was decided to use minimal API consisting of several function in lib/gradelib.php and each mod/xxx/lib.php<br />
<br />
=== Activity grade settings ===<br />
Activity settings are stored in mod_form.php. For example, the forum configuration form is in /mod/forum/mod_form.php. This file contains a class which extends moodleform_mod. The method definition() calls $this->standard_grading_coursemodule_elements(); which inserts standard grade related elements.<br />
<br />
To control which elements are displayed the activity's lib.php should contain a (activityname)_supports() method such as this to describe what features it supports.<br />
<br />
<code php><br />
function forum_supports($feature) {<br />
switch($feature) {<br />
case FEATURE_GROUPS: return true;<br />
case FEATURE_GROUPINGS: return true;<br />
case FEATURE_GROUPMEMBERSONLY: return true;<br />
case FEATURE_MOD_INTRO: return true;<br />
case FEATURE_COMPLETION_TRACKS_VIEWS: return true;<br />
case FEATURE_COMPLETION_HAS_RULES: return true;<br />
case FEATURE_GRADE_HAS_GRADE: return true;<br />
case FEATURE_GRADE_OUTCOMES: return true;<br />
case FEATURE_RATE: return true;<br />
case FEATURE_BACKUP_MOODLE2: return true;<br />
default: return null;<br />
}<br />
}<br />
</code><br />
<br />
=== Backward compatibility with Moodle 1.8 and earlier ===<br />
<br />
Function grade_grab_legacy_grades($courseid) may be used to request transfer of grades from legacy or 3rd party activities which were not yet converted to new grade API. This function is not called automatically.<br />
<br />
Modules are responsible to push existing grades into gradebook during upgrade.<br />
<br />
==API for communication with modules/blocks==<br />
<br />
Modules may use only functions from lib/gradelib.php which are marked as public. This API may be extended in later 1.9.x release. Activities should access/update only own grades.<br />
<br />
===grade_get_grades()===<br />
<br />
grade_get_grades($courseid, $itemtype, $itemmodule, $iteminstance, $userid_or_ids=0)<br />
<br />
Returns grading information for given activity - optionally with users grades. Manual, course or category items can not be queried.<br />
<br />
===grade_get_outcomes()===<br />
<br />
grade_get_outcomes($courseid, $itemtype, $itemmodule, $iteminstance,$userid=0)<br />
<br />
Returns list of outcomes used in course together with current outcomes for this user.<br />
<br />
===grade_is_locked()===<br />
<br />
grade_is_locked($courseid, $itemtype, $itemmodule, $iteminstance, $itemnumber, $userid=NULL)<br />
<br />
This function will tell a module whether a grade (or grade_item if $userid is not given) is currently locked or not. If it's locked to the current user then the module can print a nice message or prevent editing in the module. If no $userid is given, the method will always return the grade_item's locked state. If a $userid is given, the method will first check the grade_item's locked state (the column). If it is locked, the method will return true no matter the locked state of the specific grade being checked. If unlocked, it will return the locked state of the specific grade.<br />
([http://moodle.org/mod/forum/discuss.php?d=69223#p311329 info])<br />
<br />
===grade_update()===<br />
<br />
grade_update($source, $courseid, $itemtype, $itemmodule, $iteminstance, $itemnumber, $grades=NULL, $itemdetails=NULL)<br />
<br />
Submit new or update grade; update/create grade_item definition. Grade must have userid specified, rawgrade and feedback with format are optional. rawgrade NULL means 'Not graded', missing property or key means do not change existing. Only following grade item properties can be changed 'itemname', 'idnumber', 'gradetype', 'grademax', 'grademin', 'scaleid', 'multfactor', 'plusfactor', 'deleted'.<br />
<br />
===grade_update_outcomes()===<br />
<br />
grade_update_outcomes($source, $courseid, $itemtype, $itemmodule, $iteminstance, $userid, $data)<br />
<br />
Updates outcomes of a given user. Manual outcomes cannot be updated.<br />
<br />
== Private gradebook API ==<br />
Private API is used by gradebook plugins and core Moodle code, it may change in 2.0. Most of the interesting classes and functions are in lib/gradelib.php, grade/lib.php and grade/report/lib.php.<br />
<br />
The following 3 functions are all in /lib/gradelib.php<br />
<br />
===grade_regrade_final_grades()===<br />
<br />
grade_regrade_final_grades($courseid=NULL, $userid=NULL, $updated_item=NULL)<br />
<br />
Updates all grade_grades->finalgrade records for each grade_item matching the given attributes. The search is further restricted, so that only grade_items that have needs_update == true or that use calculation are retrieved and used for the update. The function returns the number of grade_items updated (NOT the same as the number of grades_grades updated!).<br />
<br />
===grade_verify_idnumber()===<br />
<br />
grade_verify_idnumber($idnumber, $grade_item = null, $cm = null, $gradeitem)<br />
<br />
Verify new value of idnumber - checks for uniqueness of new idnubmers, existing are kept intact.<br />
<br />
===remove_course_grades()===<br />
<br />
remove_course_grades($courseid, $showfeedback)<br />
<br />
Remove all grade related course data - history is kept<br />
<br />
<br />
TODO: add description of the other methods and classes + simple usage examples + querylib.php description<br />
<br />
== Dealing with multiple grades ==<br />
<br />
Modules usually produce only one grade item per activity. Optionally one or more outcomes may be attached to activities.<br />
<br />
Some activities may need to aggregate multiple ratings or attempts before sending them into the gradebook. Activities can not send variable number of items.<br />
<br />
If the gradebook receives multiple grade items from a module, then they are automatically grouped together in a unique grade category (with the same name as the module instance). See [[Development:Outcomes]] for more details.<br />
<br />
TODO: this may still be changed<br />
<br />
== Calculated grade items ==<br />
<br />
Categories or manual items maybe calculated using spreadsheet-like formulas. Formulas may reference other items from the same course only using Id numbers in double square brackets.<br />
<br />
eg: <nowiki>= MEAN([[quiz121]], [[quizend]]) + [[assignmentAXC]] + 20.0</nowiki><br />
<br />
== Regrading / updating of final grades ==<br />
<br />
TODO: describe needsupdate flag and incremental updates<br />
<br />
== Adjustment of raw grades ==<br />
Grade_item contains optional rules for adjusting the raw grade before it is cached into a final grade. These rules are processed BEFORE the calculation discussed above. Scale is never changed. Multfactor and plusfactor may be used to alter raw grades coming from activities, but it is recommended to use formulas instead.<br />
<br />
== Displaying the grades to ordinary participants ==<br />
<br />
The module takes responsibility for displaying grades within the module (to a student, say). It is recommended to use the real final grades obtained using grade_get_grades() functionBecause guidebook might force hiding, override grade, etc.<br />
<br />
For full display of grades in a whole course say, the student uses the same link as teachers use to access the gradebook. However, due to their different permissions they will only have access to specific reports. By default this is the ''User report'' report which only shows their own grades and has very few configuration options.<br />
<br />
== Locked grades ==<br />
<br />
Both whole columns and individual grades can be locked in the gradebook, via the ''locked'' field. Teachers may want to do this to prevent further changes from the modules, or from other teachers. When a grade is locked, any changes that might affect that grade are ignored. When the graded is unlocked, activities are asked to resend the latest grades.<br />
<br />
In the main GUIs the lock toggling will be achieved by clicking on a little padlock icon beside each entry or column.<br />
<br />
There is also an option to lock grade or item after some specified date.<br />
<br />
== Overridden grades ==<br />
<br />
Grades can be manually modified (overridden) in the gradebook. When this is done the entered value is always used instead of the aggregated, calculated or activity grade.<br />
<br />
Once grades have been overriden in the gradebook they become read only in the original module. The module should provide a visual indication as to why the grade cannot be modified.<br />
<br />
The need to improve how the module expresses that a grade has been overridden will be reduced by the new [https://docs.moodle.org/en/Development:Grading_interface_2.0 grading interface]<br />
<br />
== Hidden grades and categories ==<br />
<br />
Grades and categories can be hidden in the gradebook or the "categories and items" screen. When a category is hidden all the grade items within it are automatically hidden as well. When a category is un-hidden then all the grade items within it are un-hidden.<br />
<br />
The teacher always sees totals calculated from all relevant items (hidden or un-hidden)<br />
<br />
(Features below were added in 1.9.8 and 2.0)<br />
<br />
When a grade is shown its parent category will also be shown if it was hidden. MDL-21367<br />
<br />
The teacher decides what ordinary users can see in the case of totals that include hidden grades (MDL-21218, in 1.9.8 and 2.0). The user and overview report each have a setting to choose between:<br />
<br />
# Hide any totals that are dependent on a hidden item (show a hyphen there) [DEFAULT]<br />
# Display totals excluding the hidden items<br />
# Display full totals including the hidden items (may allow students to back-calculate hidden grades)<br />
<br />
== Logging ==<br />
<br />
All grading related changes maybe logged in history tables.<br />
<br />
== Security Issues ==<br />
<br />
For security an option to force SSL for the gradebook might be good.<br />
<br />
==Overall grade==<br />
<br />
Each course has exactly one course grade item. It may be used for this purpose now. Other course completion criteria will be implemented in 2.0.<br />
<br />
== Report plugins ==<br />
All the main interface of the gradebook are implemented as report plugins. Each plugin is fully responsible for page layout, there are some handy functions in grade/lib.php. They can even define their own capabilities and extra tables if the core tables are not enough, as they'll have a full /grade/report/xxxx/db directory.<br />
<br />
Each report defines one capability to allow people to see that report, so that admins have control over who can see what reports. For example, the participant interface can be a totally separate report plugin.<br />
<br />
This allows for the widest flexibility and safety in how grades are presented.<br />
<br />
=== Default teacher interface ===<br />
This interface will be what teachers see by default, and will subsume everything the current interface (in Moodle 1.8) does.<br />
<br />
Some snippets of functionality:<br />
{{Moodle 1.9}}<br />
Overall it's a grid, with participant names down one side and grade items along the top. <br />
<br />
Columns will be able to be collapsed together by grouping them into categories. Grades for categories can be calculated via various means. <br />
<br />
“Eye-cons” on the columns and checkboxes by every grade (this bit possibly controlled with a switch) allow hiding by category, by column, by individual grade.<br />
<br />
Textual notes can be added to each grade for more info. These show up to participants as well.<br />
<br />
A groups menu allows the teacher to switch between showing EACH of the groups they have access to, or ALL the groups they have access to.<br />
<br />
All grade items will link to modulepath/grade.php?id=44 which will work out what the current person should be allowed to see and either redirect them to the correct page or just show them immediately. This copes with situations like the quiz, say, where we want editing teachers to go to the detailed reports there while participants just see their own grade or whatever the quiz is set to show.<br />
<br />
User preference to SWITCH between showing raw grades, percentage grades, or both, or grade letters (A/B/C etc). <br />
<br />
Settings for grade letters not only define the transformation from percentage to grades, but also the transformation from letters to grades (in case the teacher edits some of the letter grades).<br />
<br />
Categories are shown above the headings for each column. Clicking for more info on a category will just show the category with a summary column showing total/average for just that category (PLUS the summary column for the whole course).<br />
<br />
All columns should be sortable up/down.<br />
<br />
At the bottom of each column is a row with the mean course score. If in groups mode, then add ANOTHER row with just the group mean. Add the number of grades used in brackets. eg 56% (11). When the report is paged, these means are still for the whole course/group (not the page!)<br />
<br />
{{Moodle 2.0}}<br />
<br />
Teachers can type “straight into” the grid using AJAX or fallback to forms. No popup menus for values.<br />
<br />
Later on we can support customisable shorthand codes to make data entry quick (eg type 'ab' for absent, or 'nge' for not good enough).<br />
<br />
See [http://test.moodle.com/grade/report/grader/index.php?id=2 the test site] for a live demo of this report.<br />
<br />
=== Default participant interface ===<br />
This interface will be what participants see by default:<br />
<br />
Some snippets of functionality:<br />
<br />
*Invert the grid to show one item per row, with the total/average at the bottom.<br />
*Use second/third columns to show categories.<br />
*Include ranking score in another column.<br />
*Show feedback<br />
*Show percentage<br />
*No editing functionality.<br />
<br />
See [http://test.moodle.com/grade/report/user/index.php?id=2 the test site] for a live demo of this report.<br />
<br />
=== Outcomes report ===<br />
This simple informational report displays all the outcomes used by the course, with the following information:<br />
<br />
*Outcome name<br />
*Overall average: If the outcome is used by more than one activity, this shows you the mean across all these activities in the current course<br />
*Site-wide: Yes or No: A site-wide outcome is automatically made available to all courses.<br />
*Activities: A list of links to the activities in the current course that use each outcome. One row per activity (table splits here)<br />
*Average: For each activity using the outcome, the average score is shown.<br />
*Number of grades: For each activity using the outcome, the number of grades is shown (non-graded participants are ignored)<br />
<br />
See [http://test.moodle.com/grade/report/outcomes/index.php?id=2 the test site] for a live demo of this report.<br />
<br />
=== Overview report ===<br />
Another basic report, showing a participant's course averages in each of the courses in which s/he has received grades.<br />
<br />
See [http://test.moodle.com/grade/report/overview/index.php the test site] for a live demo of this report.<br />
<br />
== Export plugins ==<br />
<br />
The API for these is extremely simple. Each export plugin should occupy a directory under /grade/export/xyz and needs to provide only an index.php file as a the primary interface. This file just accepts a 'courseid' parameter.<br />
<br />
== Import plugins ==<br />
<br />
Each import plugin should occupy a directory under /grade/import/xyz and needs to provide only an index.php file as a the primary interface. This file just accepts a 'courseid' parameter.<br />
<br />
The index.php will show an interface for further options and selections.<br />
<br />
Import plugin must validate data before starting the import operation, if some parts of import fail the user must be notified.<br />
<br />
Some sample import plugins are:<br />
<br />
===Import from CSV===<br />
<br />
Accepts an upload of (or URL to) a CSV file. Multiple options describe how to process the file, which columns to add etc. The imported grades always override current grades.<br />
<br />
===Import from XML===<br />
<br />
Accepts an upload of (or URL to) an XML file with this kind of format (from OU). <br />
<br />
<results batch="[someuniqueimportnumber]"><br />
<result><br />
<state>['new' or 'regrade']</state><br />
<assignment>[idnumber]</assignment><br />
<student>[studentid]</student><br />
<score>[score]</score><br />
</result><br />
<result><br />
<state>['new' or 'regrade']</state><br />
<assignment>[idnumber]</assignment><br />
<student>[studentid]</student><br />
<score>[score]</score><br />
</result><br />
[...]<br />
</results><br />
<br />
== Capabilities and Permissions ==<br />
<br />
* moodle/grade:view - view own grades or grades of other user if used in CONTEXT_USER<br />
<br />
* moodle/grade:viewall - view grades of all users<br />
<br />
* moodle/grade:viewhidden - see grades that are marked as hidden for the owner<br />
<br />
* moodle/grade:hide - be able to hide/unhide cells, items or categories<br />
<br />
* moodle/grade:lock - be able to lock cells, items or categories<br />
<br />
* moodle/grade:unlock - be able to unlock cells, items or categories<br />
<br />
* moodle/grade:manage - manage grade items and categories in gradebook (create, edit, lock, hide, delete, etc.)<br />
<br />
* moodle/grade:import - general import grades, requires separate permission for each plugin<br />
<br />
* moodle/grade:export - export grades, requires separate permission for each plugin<br />
<br />
* gradereport/grader:view - can view the grader report<br />
<br />
* gradeimport/csv:view - can view/use the csv import plugin<br />
<br />
* gradeexport/csv:view - can view/use the csv export plugin<br />
<br />
* moodle:site/accessallgroups<br />
<br />
== Development Tasks and Tracking ==<br />
<br />
For details of 1.9 development see [http://tracker.moodle.org/browse/MDL-9137 MDL-9137]<br />
<br />
For details of 2.0 development see [https://docs.moodle.org/en/Development:Gradebook_improvements Gradebook_imporovements] and [http://tracker.moodle.org/browse/MDL-19131 MDL-19131]<br />
<br />
==Updating module code==<br />
Module authors must implement new gradebook API and add upgrade code for migration of old grades into new gradebook. Fortunately the needed changes are not big.<br />
<br />
Steps:<br />
*add xxx_update_grades() function into mod/xxx/lib.php<br />
*add xxx_grade_item_update() function into mod/xxx/lib.php<br />
*patch xxx_update_instance(), xxx_add_instance() and xxx_delete_instance() to call xxx_grade_item_update()<br />
*patch all places of code that change grade values to call xxx_update_grades()<br />
*patch code that displays grades to students to use final grades from the gradebook<br />
<br />
There are many examples in official modules, assignment has the most advanced implementation.<br />
<br />
== Ideas for the future ==<br />
{{Moodle 2.1}}<br />
See [[Development:Gradebook_improvements]] and MDL-25423 for details of planned future enhancements<br />
<br />
*option to aggregate including/excluding hidden grades - needs db changes<br />
*option to rollback all changes during import operation if anything fails<br />
*performance improvements<br />
*conditional activities<br />
*course completion criteria<br />
*better public API for modules<br />
*better API for gradebook plugins<br />
*better state tracking in export plugins<br />
*ajax reports<br />
*specialised reports<br />
*submission and marking date tracking db changes<br />
*calculation formula improvements<br />
*historical views<br />
*individual graph of grades (time vs %). Bar graph, lineal graph. Add (or not) the maximum posible; line of 0 (=minimum), 25, 50 (=median), 75 and 100 (=max) percentils of the group<br />
<br />
== See also ==<br />
<br />
* [http://moodle.org/mod/forum/discuss.php?d=69223&mode=3 Gradebook Development ideas] forum discussion<br />
* Using Moodle [http://moodle.org/mod/forum/discuss.php?d=51107 New gradebook for Moodle] forum discussion<br />
* [[Development:Gradebook Report Tutorial]]<br />
<br />
[[Category:Developer|Grades]]<br />
[[Category:Grades]]</div>Andyjdavishttps://docs.moodle.org/20/en/index.php?title=Development:Grades&diff=79041Development:Grades2010-12-10T04:11:04Z<p>Andyjdavis: /* Ideas for the future */</p>
<hr />
<div>{{Work in progress}}<br />
<br />
== Executive Summary ==<br />
<br />
This document primarily describes the current workings of the gradebook. For more detailed information about current gradebook development see [[Development:Gradebook_improvements]]<br />
<br />
The gradebook mechanisms must be rebuilt to:<br />
<br />
# '''Improve performance and scalability''' - All grades from throughout the system will be pushed to a central system of tables. This means reports based on grades can be generated much faster, and the gradebook has ultimate control over the content.<br />
# '''Improve flexibility''' - All aspects of the new gradebook will use simple plugin structures, namely: exports, imports and displays/reports. It is expected that the community will be very active in producing [[Development:Gradebook Report Tutorial |special-purpose reports]] analysing the basic grade data in new ways, for example, or writing plugins to transfer grades to student information systems.<br />
# '''Allow rubrics for outcomes (aka standards,competencies,goals)''' - As well as numerical grades, each grading item can consist of a number of scores made on a rubric against a standard outcome statement. These can be automatically converted to a numerical grade if desired or just shown as is.<br />
# '''Allow arbitrary columns and derived columns''' - Arbitrary columns of data can be added (either manually or via import). Columns can also be automatically filled based on formulas.<br />
# '''Implement limited public API''' - Activities may use this API to send grades/outcomes to gradebook and find out the final grades.<br />
<br />
== Glossary ==<br />
<br />
Here are some terms used in the gradebook, both in the development and the user interface. Using these terms in discussions about the gradebook will help to reduce confusion.<br />
<br />
{| class="nicetable"<br />
!Term<br />
!Definition<br />
|-<br />
|Activity<br />
|An instance of an activity module [[Category:Modules|Module]] (e.g. a single quiz, assignment etc...)<br />
|-<br />
|Calculation<br />
|A formula used to calculate grades, based (optionally) on other grade items. Not the same as [[Calculated_question_type|Calculated question types]].<br />
|-<br />
|Category<br />
|A set of Grade Items. A Category also has its own aggregated Grade which is calculated from its Grade Items. There is no limit to the level of nesting of Categories (a Category may belong to another Category). However, each Grade Item may belong to only one Category. <br />
|-<br />
|Course completion<br />
|The concept of meeting certain criteria for completing a course. In the context of the gradebook, this means a set of grades that must be reached, or a number of outcomes/competencies to complete/master.<br />
|-<br />
|Grade<br />
|A Grade is a single assessment. It may be a number or an item on a scale (possibly tied to an Outcome). Raw grade value is the numerical or scale grade from activity. Final grade is the grade reported in gradebook.<br />
|-<br />
|[[Gradebook|Gradebook]]<br />
|A central location in Moodle where students' Grades are stored and displayed. Teachers can keep track of their students' progress and organise which set of Grades their students will be able to see. Students see their own Grades.<br />
|-<br />
|Grade Item<br />
|A "column" of Grades. It can be created from a specific Activity or other module, calculated from other Grade Items, or entered manually.<br />
|-<br />
|[[Development:Grades#Locked_grades|Grade Locks]]<br />
|See linked section of this page<br />
|-<br />
|History<br />
|The gradebook has its own type of log, which keeps a History of all changes made to grades.<br />
|-<br />
|[[Development:Outcomes|Outcome]]<br />
|[[Development:Outcomes|Outcomes]] are specific descriptions of what a person is expected to be able to do or understand at the completion of an activity or course. An activity might have more than one outcome, and each may have a grade against it (usually on a scale). Other terms for Outcomes are ''Competencies'' and ''Goals''. See some [[Development:Outcomes_examples|Examples]].<br />
|-<br />
|[[Scales|Scale]]<br />
|A scale is a set of responses from which the teacher can choose one. eg Very cool, Cool, Fairly cool, Not very cool, Not cool<br />
|-<br />
|Letter Grades<br />
|Special representation of grade values similar to scales. Letters are configured in course contexts or above and are defined by lower boundary. eg A (above 90 %), B (above 80 %), C (above 70 %), D (above 50 %), F (above 0 %)<br />
<br />
|}<br />
<br />
== Database structures ==<br />
=== grade_items ===<br />
<br />
This table keeps information about gradeable items (ie columns). If an activity (eg an assignment or quiz) has multiple grade_items associated with it (eg several outcomes and numerical grade), then there will be a corresponding multiple number of rows in this table.<br />
<br />
idnumber is a tag unique inside a course identifying the grade item, useful for identifying data in exports and for referring to the grade item in calculations. It is the same as the idnumber in course_modules.<br />
<br />
<br />
{| border="1" cellpadding="2" cellspacing="0"<br />
|'''Field''' <br />
|'''Type''' <br />
|'''Default''' <br />
|'''Info''' <br />
|-<br />
|'''id''' <br />
|int(10) <br />
|<br />
|autoincrementing <br />
|-<br />
|'''courseid''' <br />
|int(10) <br />
|<br />
|The course this item is part of <br />
|-<br />
|'''categoryid''' <br />
|int(10) <br />
|<center>NULL</center> <br />
|the category group this item belongs to <br />
|-<br />
|itemname <br />
|varchar(255) <br />
|<center>NULL</center> <br />
|The name of this item (pushed in by the module or entered by user) <br />
|-<br />
|'''itemtype''' <br />
|varchar(30) <br />
|<br />
|'mod', 'blocks', 'manual', 'course', 'category' etc <br />
|-<br />
|itemmodule <br />
|varchar(30) <br />
|<center>NULL</center> <br />
|'forum', 'quiz', 'csv', etc <br />
|-<br />
|iteminstance <br />
|int(10) <br />
|<center>NULL</center> <br />
|id of the item module <br />
|-<br />
|itemnumber <br />
|int(10) <br />
|<center>NULL</center> <br />
|Can be used to distinguish multiple grades for an activity <br />
|-<br />
|iteminfo <br />
|text <br />
|<center>NULL</center> <br />
|Info and notes about this item XXX <br />
|-<br />
|'''idnumber'''<br />
|varchar(255) <br />
|<center>NULL</center> <br />
|Arbitrary idnumber provided by the module responsible (optional and course unique)<br />
|-<br />
|calculation <br />
|text<br />
|<center>NULL</center> <br />
|Spreadsheet-type formula used to process the raw grades into final grades<br />
|-<br />
|'''gradetype''' <br />
|int(4) <br />
|<center>1</center> <br />
|0 = none, 1 = value, 2 = scale, 3 = text <br />
|-<br />
|grademax <br />
|float(10,5) <br />
|<center>100</center> <br />
|What is the maximum allowable grade? <br />
|-<br />
|grademin <br />
|float(10,5) <br />
|<center>0</center> <br />
|What is the minimum allowable grade? <br />
|-<br />
|'''scaleid''' <br />
|int(10) <br />
|<center>NULL</center> <br />
|If this grade is based on a scale, which one is it? <br />
|-<br />
|'''outcomeid''' <br />
|int(10) <br />
|<center>NULL</center> <br />
|If this is outcome item, which outcome is it? <br />
|-<br />
|gradepass<br />
|float(10,5) <br />
|<center>0</center> <br />
|What grade is needed to pass? grademin <= gradepass <= grademax<br />
|-<br />
|multfactor <br />
|float(10,5) <br />
|<center>1.0</center> <br />
|Multiply all raw grades from activities by this <br />
|-<br />
|plusfactor <br />
|float(10,5) <br />
|<center>0.0</center> <br />
|Add this to all raw grades from activities by this <br />
|-<br />
|aggregationcoef <br />
|float(10,5) <br />
|<center>0.0</center> <br />
|Weight applied to all grades in this grade item during aggregation with other grade items.<br />
|-<br />
|sortorder <br />
|int(10) <br />
|<center>0</center> <br />
|Sorting order of the columns (pre-order walk of the grading tree)<br />
|-<br />
|display<br />
|int(10) <br />
|<center>0</center> <br />
|Display as real grades, percentages (in reference to the minimum and maximum grades) or letters (A, B, C etc..), or course default (0)<br />
|-<br />
|hidden <br />
|int(10) <br />
|<center>0</center> <br />
|1 is hidden, 1 is hide always, > 1 is a date to hide until (prevents viewing of all user grades) <br />
|-<br />
|'''locked'''<br />
|int(10) <br />
|<center>0</center> <br />
|0 is not locked, > 0 is a date when was item locked (no final grade or grade_item updates possible)<br />
|-<br />
|'''locktime'''<br />
|int(10) <br />
|<center>0</center> <br />
|0 no auto locking, > 0 is a date to lock grade item and final grades after automatically <br />
|-<br />
|deleted <br />
|int(10) <br />
|<center>0</center> <br />
|1 means the associated module instance has been deleted<br />
|-<br />
|'''needsupdate'''<br />
|int(10) <br />
|<center>0</center> <br />
|If this flag is set, then the whole column will be recalculated. If set in course item, some other item needs recalculation. Calculated and category items are recalculated together with any other items.<br />
|-<br />
|timecreated <br />
|int(10)<br />
|<br />
|The first time this grade_item was created<br />
|-<br />
|timemodified <br />
|int(10)<br />
|<br />
|The last time this grade_item was modified<br />
|}<br />
<br />
=== grade_categories ===<br />
<br />
This table keeps information about categories, used for grouping items. An associated grade_item will be maintained for each category to store the aggregate data.<br />
<br />
{| border="1" cellpadding="2" cellspacing="0"<br />
|'''Field''' <br />
|'''Type''' <br />
|'''Default''' <br />
|'''Info''' <br />
|-<br />
|'''id''' <br />
|int(10) <br />
|<br />
|autoincrementing <br />
|-<br />
|'''courseid''' <br />
|int(10) <br />
|<br />
|The course this grade category is part of <br />
|-<br />
|'''parent''' <br />
|int(10) <br />
|<center>NULL</center> <br />
|Parent grade_category (hierarchical)<br />
|-<br />
|depth<br />
|int(10) <br />
|<center>0</center> <br />
|How deep is this category from the highest level (1,2,3)<br />
|-<br />
|path<br />
|varchar(255) <br />
| <br />
|Shows the path as /1/2/3/ <br />
|-<br />
|fullname <br />
|varchar(255) <br />
|<br />
|The name of this grade category <br />
|-<br />
|aggregation <br />
|int(10) <br />
|<center>0</center> <br />
|A constant pointing to one of the predefined aggregation strategies (none, mean,median,sum, etc) <br />
|-<br />
|keephigh <br />
|int(10) <br />
|<center>0</center> <br />
|Keep only the X highest items <br />
|-<br />
|droplow <br />
|int(10) <br />
|<center>0</center> <br />
|Drop the X lowest items <br />
|-<br />
|aggregateonlygraded<br />
|int(1) <br />
|<center>0</center> <br />
|Aggregate only existing grades <br />
|-<br />
|aggregateoutcomes<br />
|int(1) <br />
|<center>0</center> <br />
|Aggregate otcomes together with normal items <br />
|-<br />
|aggregatesubcats<br />
|int(1) <br />
|<center>0</center> <br />
|Aggregate only items placed directly in category or all items in subcategories excluding the subcategory totals <br />
|-<br />
|timecreated<br />
|int(10) <br />
|<br />
|The first time this grade_category was created<br />
|-<br />
|timemodified <br />
|int(10) <br />
|<br />
|The last time this grade_category was modified<br />
|}<br />
<br />
=== grade_grades ===<br />
<br />
This table keeps individual grades for each user and each item. The raw grade is exactly as imported or submitted by modules. The rawgrademax/min and rawscaleid are stored here to record the values at the time the grade was stored, because teachers might change this for an activity! All the results are normalised/resampled/calculated for the finalgrade, which is relative to the max/min/scaleid values stored in the grade_item. The finalgrade field is effectively a cache and values are rebuilt whenever raw values or the grade_item changes.<br />
<br />
Note that the finalgrade for a scale-based item may be non-integer! It needs to be rounded on display.<br />
<br />
{| border="1" cellpadding="2" cellspacing="0"<br />
|'''Field''' <br />
|'''Type''' <br />
|'''Default''' <br />
|'''Info''' <br />
|-<br />
|'''id''' <br />
|int(10) <br />
|<br />
|autoincrementing <br />
|-<br />
|'''itemid''' <br />
|int(10) <br />
|<br />
|The item this grade belongs to <br />
|-<br />
|'''userid''' <br />
|int(10) <br />
|<br />
|The user who this grade is for <br />
|-<br />
|rawgrade<br />
|float(11,10) <br />
|<center>NULL</center> <br />
|The raw grade that came into the system<br />
|-<br />
|rawgrademax <br />
|float(11,10) <br />
|<center>100</center> <br />
|The maximum allowable grade when this was created <br />
|-<br />
|rawgrademin <br />
|float(11,10) <br />
|<center>0</center> <br />
|The minimum allowable grade when this was created <br />
|-<br />
|'''rawscaleid''' <br />
|int(10) <br />
|<center>NULL</center> <br />
|If this grade is based on a scale, which one was it? <br />
|-<br />
|'''usermodified'''<br />
|int(10) <br />
|<center>NULL</center> <br />
|the userid of the person who last modified the raw grade value<br />
|-<br />
|finalgrade<br />
|float(11,10) <br />
|<center>NULL</center> <br />
|The final grade (cached) after all calculations are made. Overriden grades are also stored here.<br />
|- <br />
|hidden <br />
|int(10) <br />
|<center>0</center> <br />
|0 is not hidden, 1 is hide always, > 1 is a date to hide until <br />
|-<br />
|'''locked'''<br />
|int(10) <br />
|<center>0</center> <br />
|0 is not locked, > 0 when was the grade locked<br />
|-<br />
|'''locktime'''<br />
|int(10) <br />
|<center>0</center> <br />
|0 is never, > 0 is a date to lock the final grade after automatically<br />
|-<br />
|exported <br />
|int(10) <br />
|<center>0</center> <br />
|0 is not exported, > 0 is the last exported date <br />
|-<br />
|excluded <br />
|int(10) <br />
|<center>0</center> <br />
|grade excluded from aggregation, > 0 is the last exported date <br />
|-<br />
|overridden <br />
|int(10) <br />
|<center>0</center> <br />
|0 is not overridden, > 0 is the last overridden date <br />
|-<br />
|feedback <br />
|text <br />
|<center>NULL</center> <br />
|Manual feedback from the teacher. Could be a code like 'mi'. <br />
|-<br />
|feedbackformat<br />
|int(10)<br />
|<center>0</center> <br />
|Text format for feedback<br />
|-<br />
|information <br />
|text <br />
|<center>NULL</center> <br />
|not sued yet (Further information like forum rating distribution 4/5/7/0/1 ?)<br />
|-<br />
|informationformat<br />
|int(10)<br />
|<center>0</center> <br />
|Text format for information<br />
|-<br />
|timecreated<br />
|int(10) <br />
|<br />
|temporary hack - the date of submission in activity if any, new field expected in 2.0<br />
|-<br />
|timemodified<br />
|int(10) <br />
|<br />
|temporary hack - the date of grading in activity or date of manual grading in gradebook, new field expected in 2.0<br />
|}<br />
<br />
=== grade_outcomes ===<br />
<br />
This table describes the outcomes used in the system. An outcome is a statement tied to a rubric scale from low to high, such as “Not met, Borderline, Met” (stored as 0,1 or 2). For more info about these see [[Development:Outcomes]].<br />
<br />
{| border="1" cellpadding="2" cellspacing="0"<br />
|'''Field''' <br />
|'''Type''' <br />
|'''Default''' <br />
|'''Info''' <br />
<br />
|-<br />
|'''id''' <br />
|int(10) <br />
|<br />
|autoincrementing <br />
<br />
|-<br />
|'''courseid''' <br />
|int(10) <br />
|<center>NULL</center> <br />
|Mostly these are defined site wide ie NULL <br />
<br />
|-<br />
|shortname <br />
|varchar(255) <br />
|<br />
|The short name or code for this outcome statement <br />
<br />
|-<br />
|fullname <br />
|text <br />
|<br />
|The full description of the outcome (usually 1 sentence) <br />
<br />
|-<br />
|'''scaleid''' <br />
|int(10) <br />
|<br />
|The recommended scale for this outcome. <br />
|-<br />
|description <br />
|text <br />
|<center>NULL</center> <br />
|The full description of the outcome (usually 1 sentence) <br />
|-<br />
|timecreated<br />
|int(10) <br />
|<br />
|the time this outcome was first created <br />
<br />
|-<br />
|timemodified<br />
|int(10) <br />
|<br />
|the time this outcome was last updated <br />
<br />
|-<br />
|'''usermodified'''<br />
|int(10) <br />
|<center>NULL</center> <br />
|the userid of the person who last modified this outcome<br />
|}<br />
<br />
=== grade_outcomes_courses ===<br />
An intersection table used to make standard outcomes available to courses.<br />
<br />
{| border="1" cellpadding="2" cellspacing="0"<br />
|'''Field''' <br />
|'''Type''' <br />
|'''Default''' <br />
|'''Info''' <br />
<br />
|-<br />
|'''id''' <br />
|int(10) <br />
|<br />
|autoincrementing <br />
<br />
|-<br />
|'''courseid'''<br />
|int(10)<br />
|<br />
|The id of the course being assigned the outcome<br />
<br />
|-<br />
|'''outcomeid''' <br />
|int(10) <br />
|<br />
|The id of the outcome being assigned to the course<br />
|}<br />
<br />
=== grade_import_newitem ===<br />
<br />
{| border="1" cellpadding="2" cellspacing="0"<br />
|'''Field''' <br />
|'''Type''' <br />
|'''Default''' <br />
|'''Info''' <br />
<br />
|-<br />
|'''id''' <br />
|int(10) <br />
|<br />
|autoincrementing <br />
<br />
|-<br />
|itemname<br />
|varchar(255)<br />
|<br />
|*TODO* Document<br />
<br />
|-<br />
|importcode<br />
|int(12) <br />
|<br />
|*TODO* Document <br />
|}<br />
<br />
=== grade_import_values ===<br />
<br />
{| border="1" cellpadding="2" cellspacing="0"<br />
|'''Field''' <br />
|'''Type''' <br />
|'''Default''' <br />
|'''Info''' <br />
<br />
|-<br />
|'''id''' <br />
|int(10) <br />
|<br />
|autoincrementing <br />
<br />
|-<br />
|'''itemid''' <br />
|int(10) <br />
|NULL<br />
|*TODO* Document <br />
<br />
|-<br />
|newgradeitem<br />
|int(10)<br />
|NULL<br />
|*TODO* Document<br />
<br />
|-<br />
|'''userid''' <br />
|int(10) <br />
|<br />
|*TODO* Document <br />
<br />
|-<br />
|finalgrade<br />
|float(10,5) <br />
|NULL<br />
|*TODO* Document <br />
<br />
|-<br />
|feedback<br />
|text<br />
|NULL<br />
|*TODO* Document <br />
<br />
|-<br />
|importcode<br />
|int(12) <br />
|<br />
|*TODO* Document <br />
|}<br />
<br />
=== History tables ===<br />
<br />
These table keep track of changes to most of the grade tables. Using these it should be possible to reconstruct the grades at any point in time in the past, or to audit grade changes over time. It should be quicker to use these tables for that, rather than storing this information in the main Moodle log. The following tables are set up for that purpose:<br />
<br />
#grade_categories_history<br />
#grade_grades_history<br />
#grade_items_history<br />
#grade_outcomes_history<br />
<br />
Each of them has exactly the same DB structure as their matching table (e.g. grade_categories), with 3 extra fields:<br />
<br />
<br />
<br />
{| border="1" cellpadding="2" cellspacing="0"<br />
|'''Field''' <br />
|'''Type''' <br />
|'''Default''' <br />
|'''Info''' <br />
<br />
|-<br />
|action<br />
|int(10) <br />
|0<br />
|The action that lead to the change being recorded (insert, update, delete)<br />
<br />
|-<br />
|'''oldid''' <br />
|int(10) <br />
|<br />
|The id of the record being changed or inserted (PK of the main table, not the history table) <br />
<br />
|-<br />
|source<br />
|varchar(255)<br />
|NULL<br />
|The module from which the action originated <br />
|}<br />
<br />
=== grade_letters ===<br />
<br />
{| border="1" cellpadding="2" cellspacing="0"<br />
|'''Field''' <br />
|'''Type''' <br />
|'''Default''' <br />
|'''Info''' <br />
<br />
|-<br />
|'''id''' <br />
|int(10) <br />
|<br />
|autoincrementing <br />
<br />
|-<br />
|contextid<br />
|int(10)<br />
|<br />
|What contextid does this letter apply to (from levels CONTEXT_SYSTEM, CONTEXT_COURSECAT or CONTEXT_COURSE)<br />
<br />
|-<br />
|lowerboundary<br />
|float(10,5) <br />
|<br />
|The lower boundary of the letter. Its upper boundary is the lower boundary of the next highest letter, unless there is none above, in which case it's grademax for that grade_item.<br />
<br />
|-<br />
|letter<br />
|varchar(255) <br />
|<br />
|The display value of the letter. Can be any character or string of characters (OK, A, 10% etc..) <br />
|}<br />
<br />
== Overview of module communication ==<br />
<br />
Modules usually store raw grades internally and pass them into gradebook every time they change. Gradebook may also request activities to resend the grades. <br />
<br />
The gradebook is designed to be as separate as possible from the code of activities - modules do not read grade tables or use internal gradebook API. <br />
<br />
Originally it was planned to use new events API, but in the end it was decided to use minimal API consisting of several function in lib/gradelib.php and each mod/xxx/lib.php<br />
<br />
=== Backward compatibility with Moodle 1.8 and earlier ===<br />
<br />
Function grade_grab_legacy_grades($courseid) may be used to request transfer of grades from legacy or 3rd party activities which were not yet converted to new grade API. This function is not called automatically.<br />
<br />
Modules are responsible to push existing grades into gradebook during upgrade.<br />
<br />
==API for communication with modules/blocks==<br />
<br />
Modules may use only functions from lib/gradelib.php which are marked as public. This API may be extended in later 1.9.x release. Activities should access/update only own grades.<br />
<br />
===grade_get_grades()===<br />
<br />
grade_get_grades($courseid, $itemtype, $itemmodule, $iteminstance, $userid_or_ids=0)<br />
<br />
Returns grading information for given activity - optionally with users grades. Manual, course or category items can not be queried.<br />
<br />
===grade_get_outcomes()===<br />
<br />
grade_get_outcomes($courseid, $itemtype, $itemmodule, $iteminstance,$userid=0)<br />
<br />
Returns list of outcomes used in course together with current outcomes for this user.<br />
<br />
===grade_is_locked()===<br />
<br />
grade_is_locked($courseid, $itemtype, $itemmodule, $iteminstance, $itemnumber, $userid=NULL)<br />
<br />
This function will tell a module whether a grade (or grade_item if $userid is not given) is currently locked or not. If it's locked to the current user then the module can print a nice message or prevent editing in the module. If no $userid is given, the method will always return the grade_item's locked state. If a $userid is given, the method will first check the grade_item's locked state (the column). If it is locked, the method will return true no matter the locked state of the specific grade being checked. If unlocked, it will return the locked state of the specific grade.<br />
([http://moodle.org/mod/forum/discuss.php?d=69223#p311329 info])<br />
<br />
===grade_update()===<br />
<br />
grade_update($source, $courseid, $itemtype, $itemmodule, $iteminstance, $itemnumber, $grades=NULL, $itemdetails=NULL)<br />
<br />
Submit new or update grade; update/create grade_item definition. Grade must have userid specified, rawgrade and feedback with format are optional. rawgrade NULL means 'Not graded', missing property or key means do not change existing. Only following grade item properties can be changed 'itemname', 'idnumber', 'gradetype', 'grademax', 'grademin', 'scaleid', 'multfactor', 'plusfactor', 'deleted'.<br />
<br />
===grade_update_outcomes()===<br />
<br />
grade_update_outcomes($source, $courseid, $itemtype, $itemmodule, $iteminstance, $userid, $data)<br />
<br />
Updates outcomes of a given user. Manual outcomes cannot be updated.<br />
<br />
== Private gradebook API ==<br />
Private API is used by gradebook plugins and core Moodle code, it may change in 2.0. Most of the interesting classes and functions are in lib/gradelib.php, grade/lib.php and grade/report/lib.php.<br />
<br />
The following 3 functions are all in /lib/gradelib.php<br />
<br />
===grade_regrade_final_grades()===<br />
<br />
grade_regrade_final_grades($courseid=NULL, $userid=NULL, $updated_item=NULL)<br />
<br />
Updates all grade_grades->finalgrade records for each grade_item matching the given attributes. The search is further restricted, so that only grade_items that have needs_update == true or that use calculation are retrieved and used for the update. The function returns the number of grade_items updated (NOT the same as the number of grades_grades updated!).<br />
<br />
===grade_verify_idnumber()===<br />
<br />
grade_verify_idnumber($idnumber, $grade_item = null, $cm = null, $gradeitem)<br />
<br />
Verify new value of idnumber - checks for uniqueness of new idnubmers, existing are kept intact.<br />
<br />
===remove_course_grades()===<br />
<br />
remove_course_grades($courseid, $showfeedback)<br />
<br />
Remove all grade related course data - history is kept<br />
<br />
<br />
TODO: add description of the other methods and classes + simple usage examples + querylib.php description<br />
<br />
== Dealing with multiple grades ==<br />
<br />
Modules usually produce only one grade item per activity. Optionally one or more outcomes may be attached to activities.<br />
<br />
Some activities may need to aggregate multiple ratings or attempts before sending them into the gradebook. Activities can not send variable number of items.<br />
<br />
If the gradebook receives multiple grade items from a module, then they are automatically grouped together in a unique grade category (with the same name as the module instance). See [[Development:Outcomes]] for more details.<br />
<br />
TODO: this may still be changed<br />
<br />
== Calculated grade items ==<br />
<br />
Categories or manual items maybe calculated using spreadsheet-like formulas. Formulas may reference other items from the same course only using Id numbers in double square brackets.<br />
<br />
eg: <nowiki>= MEAN([[quiz121]], [[quizend]]) + [[assignmentAXC]] + 20.0</nowiki><br />
<br />
== Regrading / updating of final grades ==<br />
<br />
TODO: describe needsupdate flag and incremental updates<br />
<br />
== Adjustment of raw grades ==<br />
Grade_item contains optional rules for adjusting the raw grade before it is cached into a final grade. These rules are processed BEFORE the calculation discussed above. Scale is never changed. Multfactor and plusfactor may be used to alter raw grades coming from activities, but it is recommended to use formulas instead.<br />
<br />
== Displaying the grades to ordinary participants ==<br />
<br />
The module takes responsibility for displaying grades within the module (to a student, say). It is recommended to use the real final grades obtained using grade_get_grades() functionBecause guidebook might force hiding, override grade, etc.<br />
<br />
For full display of grades in a whole course say, the student uses the same link as teachers use to access the gradebook. However, due to their different permissions they will only have access to specific reports. By default this is the ''User report'' report which only shows their own grades and has very few configuration options.<br />
<br />
== Locked grades ==<br />
<br />
Both whole columns and individual grades can be locked in the gradebook, via the ''locked'' field. Teachers may want to do this to prevent further changes from the modules, or from other teachers. When a grade is locked, any changes that might affect that grade are ignored. When the graded is unlocked, activities are asked to resend the latest grades.<br />
<br />
In the main GUIs the lock toggling will be achieved by clicking on a little padlock icon beside each entry or column.<br />
<br />
There is also an option to lock grade or item after some specified date.<br />
<br />
== Overridden grades ==<br />
<br />
Grades can be manually modified (overridden) in the gradebook. When this is done the entered value is always used instead of the aggregated, calculated or activity grade.<br />
<br />
Once grades have been overriden in the gradebook they become read only in the original module. The module should provide a visual indication as to why the grade cannot be modified.<br />
<br />
The need to improve how the module expresses that a grade has been overridden will be reduced by the new [https://docs.moodle.org/en/Development:Grading_interface_2.0 grading interface]<br />
<br />
== Hidden grades and categories ==<br />
<br />
Grades and categories can be hidden in the gradebook or the "categories and items" screen. When a category is hidden all the grade items within it are automatically hidden as well. When a category is un-hidden then all the grade items within it are un-hidden.<br />
<br />
The teacher always sees totals calculated from all relevant items (hidden or un-hidden)<br />
<br />
(Features below were added in 1.9.8 and 2.0)<br />
<br />
When a grade is shown its parent category will also be shown if it was hidden. MDL-21367<br />
<br />
The teacher decides what ordinary users can see in the case of totals that include hidden grades (MDL-21218, in 1.9.8 and 2.0). The user and overview report each have a setting to choose between:<br />
<br />
# Hide any totals that are dependent on a hidden item (show a hyphen there) [DEFAULT]<br />
# Display totals excluding the hidden items<br />
# Display full totals including the hidden items (may allow students to back-calculate hidden grades)<br />
<br />
== Logging ==<br />
<br />
All grading related changes maybe logged in history tables.<br />
<br />
== Security Issues ==<br />
<br />
For security an option to force SSL for the gradebook might be good.<br />
<br />
==Overall grade==<br />
<br />
Each course has exactly one course grade item. It may be used for this purpose now. Other course completion criteria will be implemented in 2.0.<br />
<br />
== Report plugins ==<br />
All the main interface of the gradebook are implemented as report plugins. Each plugin is fully responsible for page layout, there are some handy functions in grade/lib.php. They can even define their own capabilities and extra tables if the core tables are not enough, as they'll have a full /grade/report/xxxx/db directory.<br />
<br />
Each report defines one capability to allow people to see that report, so that admins have control over who can see what reports. For example, the participant interface can be a totally separate report plugin.<br />
<br />
This allows for the widest flexibility and safety in how grades are presented.<br />
<br />
=== Default teacher interface ===<br />
This interface will be what teachers see by default, and will subsume everything the current interface (in Moodle 1.8) does.<br />
<br />
Some snippets of functionality:<br />
{{Moodle 1.9}}<br />
Overall it's a grid, with participant names down one side and grade items along the top. <br />
<br />
Columns will be able to be collapsed together by grouping them into categories. Grades for categories can be calculated via various means. <br />
<br />
“Eye-cons” on the columns and checkboxes by every grade (this bit possibly controlled with a switch) allow hiding by category, by column, by individual grade.<br />
<br />
Textual notes can be added to each grade for more info. These show up to participants as well.<br />
<br />
A groups menu allows the teacher to switch between showing EACH of the groups they have access to, or ALL the groups they have access to.<br />
<br />
All grade items will link to modulepath/grade.php?id=44 which will work out what the current person should be allowed to see and either redirect them to the correct page or just show them immediately. This copes with situations like the quiz, say, where we want editing teachers to go to the detailed reports there while participants just see their own grade or whatever the quiz is set to show.<br />
<br />
User preference to SWITCH between showing raw grades, percentage grades, or both, or grade letters (A/B/C etc). <br />
<br />
Settings for grade letters not only define the transformation from percentage to grades, but also the transformation from letters to grades (in case the teacher edits some of the letter grades).<br />
<br />
Categories are shown above the headings for each column. Clicking for more info on a category will just show the category with a summary column showing total/average for just that category (PLUS the summary column for the whole course).<br />
<br />
All columns should be sortable up/down.<br />
<br />
At the bottom of each column is a row with the mean course score. If in groups mode, then add ANOTHER row with just the group mean. Add the number of grades used in brackets. eg 56% (11). When the report is paged, these means are still for the whole course/group (not the page!)<br />
<br />
{{Moodle 2.0}}<br />
<br />
Teachers can type “straight into” the grid using AJAX or fallback to forms. No popup menus for values.<br />
<br />
Later on we can support customisable shorthand codes to make data entry quick (eg type 'ab' for absent, or 'nge' for not good enough).<br />
<br />
See [http://test.moodle.com/grade/report/grader/index.php?id=2 the test site] for a live demo of this report.<br />
<br />
=== Default participant interface ===<br />
This interface will be what participants see by default:<br />
<br />
Some snippets of functionality:<br />
<br />
*Invert the grid to show one item per row, with the total/average at the bottom.<br />
*Use second/third columns to show categories.<br />
*Include ranking score in another column.<br />
*Show feedback<br />
*Show percentage<br />
*No editing functionality.<br />
<br />
See [http://test.moodle.com/grade/report/user/index.php?id=2 the test site] for a live demo of this report.<br />
<br />
=== Outcomes report ===<br />
This simple informational report displays all the outcomes used by the course, with the following information:<br />
<br />
*Outcome name<br />
*Overall average: If the outcome is used by more than one activity, this shows you the mean across all these activities in the current course<br />
*Site-wide: Yes or No: A site-wide outcome is automatically made available to all courses.<br />
*Activities: A list of links to the activities in the current course that use each outcome. One row per activity (table splits here)<br />
*Average: For each activity using the outcome, the average score is shown.<br />
*Number of grades: For each activity using the outcome, the number of grades is shown (non-graded participants are ignored)<br />
<br />
See [http://test.moodle.com/grade/report/outcomes/index.php?id=2 the test site] for a live demo of this report.<br />
<br />
=== Overview report ===<br />
Another basic report, showing a participant's course averages in each of the courses in which s/he has received grades.<br />
<br />
See [http://test.moodle.com/grade/report/overview/index.php the test site] for a live demo of this report.<br />
<br />
== Export plugins ==<br />
<br />
The API for these is extremely simple. Each export plugin should occupy a directory under /grade/export/xyz and needs to provide only an index.php file as a the primary interface. This file just accepts a 'courseid' parameter.<br />
<br />
== Import plugins ==<br />
<br />
Each import plugin should occupy a directory under /grade/import/xyz and needs to provide only an index.php file as a the primary interface. This file just accepts a 'courseid' parameter.<br />
<br />
The index.php will show an interface for further options and selections.<br />
<br />
Import plugin must validate data before starting the import operation, if some parts of import fail the user must be notified.<br />
<br />
Some sample import plugins are:<br />
<br />
===Import from CSV===<br />
<br />
Accepts an upload of (or URL to) a CSV file. Multiple options describe how to process the file, which columns to add etc. The imported grades always override current grades.<br />
<br />
===Import from XML===<br />
<br />
Accepts an upload of (or URL to) an XML file with this kind of format (from OU). <br />
<br />
<results batch="[someuniqueimportnumber]"><br />
<result><br />
<state>['new' or 'regrade']</state><br />
<assignment>[idnumber]</assignment><br />
<student>[studentid]</student><br />
<score>[score]</score><br />
</result><br />
<result><br />
<state>['new' or 'regrade']</state><br />
<assignment>[idnumber]</assignment><br />
<student>[studentid]</student><br />
<score>[score]</score><br />
</result><br />
[...]<br />
</results><br />
<br />
== Capabilities and Permissions ==<br />
<br />
* moodle/grade:view - view own grades or grades of other user if used in CONTEXT_USER<br />
<br />
* moodle/grade:viewall - view grades of all users<br />
<br />
* moodle/grade:viewhidden - see grades that are marked as hidden for the owner<br />
<br />
* moodle/grade:hide - be able to hide/unhide cells, items or categories<br />
<br />
* moodle/grade:lock - be able to lock cells, items or categories<br />
<br />
* moodle/grade:unlock - be able to unlock cells, items or categories<br />
<br />
* moodle/grade:manage - manage grade items and categories in gradebook (create, edit, lock, hide, delete, etc.)<br />
<br />
* moodle/grade:import - general import grades, requires separate permission for each plugin<br />
<br />
* moodle/grade:export - export grades, requires separate permission for each plugin<br />
<br />
* gradereport/grader:view - can view the grader report<br />
<br />
* gradeimport/csv:view - can view/use the csv import plugin<br />
<br />
* gradeexport/csv:view - can view/use the csv export plugin<br />
<br />
* moodle:site/accessallgroups<br />
<br />
== Development Tasks and Tracking ==<br />
<br />
For details of 1.9 development see [http://tracker.moodle.org/browse/MDL-9137 MDL-9137]<br />
<br />
For details of 2.0 development see [https://docs.moodle.org/en/Development:Gradebook_improvements Gradebook_imporovements] and [http://tracker.moodle.org/browse/MDL-19131 MDL-19131]<br />
<br />
==Updating module code==<br />
Module authors must implement new gradebook API and add upgrade code for migration of old grades into new gradebook. Fortunately the needed changes are not big.<br />
<br />
Steps:<br />
*add xxx_update_grades() function into mod/xxx/lib.php<br />
*add xxx_grade_item_update() function into mod/xxx/lib.php<br />
*patch xxx_update_instance(), xxx_add_instance() and xxx_delete_instance() to call xxx_grade_item_update()<br />
*patch all places of code that change grade values to call xxx_update_grades()<br />
*patch code that displays grades to students to use final grades from the gradebook<br />
<br />
There are many examples in official modules, assignment has the most advanced implementation.<br />
<br />
== Ideas for the future ==<br />
{{Moodle 2.1}}<br />
See [[Development:Gradebook_improvements]] and MDL-25423 for details of planned future enhancements<br />
<br />
*option to aggregate including/excluding hidden grades - needs db changes<br />
*option to rollback all changes during import operation if anything fails<br />
*performance improvements<br />
*conditional activities<br />
*course completion criteria<br />
*better public API for modules<br />
*better API for gradebook plugins<br />
*better state tracking in export plugins<br />
*ajax reports<br />
*specialised reports<br />
*submission and marking date tracking db changes<br />
*calculation formula improvements<br />
*historical views<br />
*individual graph of grades (time vs %). Bar graph, lineal graph. Add (or not) the maximum posible; line of 0 (=minimum), 25, 50 (=median), 75 and 100 (=max) percentils of the group<br />
<br />
== See also ==<br />
<br />
* [http://moodle.org/mod/forum/discuss.php?d=69223&mode=3 Gradebook Development ideas] forum discussion<br />
* Using Moodle [http://moodle.org/mod/forum/discuss.php?d=51107 New gradebook for Moodle] forum discussion<br />
* [[Development:Gradebook Report Tutorial]]<br />
<br />
[[Category:Developer|Grades]]<br />
[[Category:Grades]]</div>Andyjdavishttps://docs.moodle.org/20/en/index.php?title=Development:Grades&diff=79040Development:Grades2010-12-10T04:10:30Z<p>Andyjdavis: /* Ideas for the future */</p>
<hr />
<div>{{Work in progress}}<br />
<br />
== Executive Summary ==<br />
<br />
This document primarily describes the current workings of the gradebook. For more detailed information about current gradebook development see [[Development:Gradebook_improvements]]<br />
<br />
The gradebook mechanisms must be rebuilt to:<br />
<br />
# '''Improve performance and scalability''' - All grades from throughout the system will be pushed to a central system of tables. This means reports based on grades can be generated much faster, and the gradebook has ultimate control over the content.<br />
# '''Improve flexibility''' - All aspects of the new gradebook will use simple plugin structures, namely: exports, imports and displays/reports. It is expected that the community will be very active in producing [[Development:Gradebook Report Tutorial |special-purpose reports]] analysing the basic grade data in new ways, for example, or writing plugins to transfer grades to student information systems.<br />
# '''Allow rubrics for outcomes (aka standards,competencies,goals)''' - As well as numerical grades, each grading item can consist of a number of scores made on a rubric against a standard outcome statement. These can be automatically converted to a numerical grade if desired or just shown as is.<br />
# '''Allow arbitrary columns and derived columns''' - Arbitrary columns of data can be added (either manually or via import). Columns can also be automatically filled based on formulas.<br />
# '''Implement limited public API''' - Activities may use this API to send grades/outcomes to gradebook and find out the final grades.<br />
<br />
== Glossary ==<br />
<br />
Here are some terms used in the gradebook, both in the development and the user interface. Using these terms in discussions about the gradebook will help to reduce confusion.<br />
<br />
{| class="nicetable"<br />
!Term<br />
!Definition<br />
|-<br />
|Activity<br />
|An instance of an activity module [[Category:Modules|Module]] (e.g. a single quiz, assignment etc...)<br />
|-<br />
|Calculation<br />
|A formula used to calculate grades, based (optionally) on other grade items. Not the same as [[Calculated_question_type|Calculated question types]].<br />
|-<br />
|Category<br />
|A set of Grade Items. A Category also has its own aggregated Grade which is calculated from its Grade Items. There is no limit to the level of nesting of Categories (a Category may belong to another Category). However, each Grade Item may belong to only one Category. <br />
|-<br />
|Course completion<br />
|The concept of meeting certain criteria for completing a course. In the context of the gradebook, this means a set of grades that must be reached, or a number of outcomes/competencies to complete/master.<br />
|-<br />
|Grade<br />
|A Grade is a single assessment. It may be a number or an item on a scale (possibly tied to an Outcome). Raw grade value is the numerical or scale grade from activity. Final grade is the grade reported in gradebook.<br />
|-<br />
|[[Gradebook|Gradebook]]<br />
|A central location in Moodle where students' Grades are stored and displayed. Teachers can keep track of their students' progress and organise which set of Grades their students will be able to see. Students see their own Grades.<br />
|-<br />
|Grade Item<br />
|A "column" of Grades. It can be created from a specific Activity or other module, calculated from other Grade Items, or entered manually.<br />
|-<br />
|[[Development:Grades#Locked_grades|Grade Locks]]<br />
|See linked section of this page<br />
|-<br />
|History<br />
|The gradebook has its own type of log, which keeps a History of all changes made to grades.<br />
|-<br />
|[[Development:Outcomes|Outcome]]<br />
|[[Development:Outcomes|Outcomes]] are specific descriptions of what a person is expected to be able to do or understand at the completion of an activity or course. An activity might have more than one outcome, and each may have a grade against it (usually on a scale). Other terms for Outcomes are ''Competencies'' and ''Goals''. See some [[Development:Outcomes_examples|Examples]].<br />
|-<br />
|[[Scales|Scale]]<br />
|A scale is a set of responses from which the teacher can choose one. eg Very cool, Cool, Fairly cool, Not very cool, Not cool<br />
|-<br />
|Letter Grades<br />
|Special representation of grade values similar to scales. Letters are configured in course contexts or above and are defined by lower boundary. eg A (above 90 %), B (above 80 %), C (above 70 %), D (above 50 %), F (above 0 %)<br />
<br />
|}<br />
<br />
== Database structures ==<br />
=== grade_items ===<br />
<br />
This table keeps information about gradeable items (ie columns). If an activity (eg an assignment or quiz) has multiple grade_items associated with it (eg several outcomes and numerical grade), then there will be a corresponding multiple number of rows in this table.<br />
<br />
idnumber is a tag unique inside a course identifying the grade item, useful for identifying data in exports and for referring to the grade item in calculations. It is the same as the idnumber in course_modules.<br />
<br />
<br />
{| border="1" cellpadding="2" cellspacing="0"<br />
|'''Field''' <br />
|'''Type''' <br />
|'''Default''' <br />
|'''Info''' <br />
|-<br />
|'''id''' <br />
|int(10) <br />
|<br />
|autoincrementing <br />
|-<br />
|'''courseid''' <br />
|int(10) <br />
|<br />
|The course this item is part of <br />
|-<br />
|'''categoryid''' <br />
|int(10) <br />
|<center>NULL</center> <br />
|the category group this item belongs to <br />
|-<br />
|itemname <br />
|varchar(255) <br />
|<center>NULL</center> <br />
|The name of this item (pushed in by the module or entered by user) <br />
|-<br />
|'''itemtype''' <br />
|varchar(30) <br />
|<br />
|'mod', 'blocks', 'manual', 'course', 'category' etc <br />
|-<br />
|itemmodule <br />
|varchar(30) <br />
|<center>NULL</center> <br />
|'forum', 'quiz', 'csv', etc <br />
|-<br />
|iteminstance <br />
|int(10) <br />
|<center>NULL</center> <br />
|id of the item module <br />
|-<br />
|itemnumber <br />
|int(10) <br />
|<center>NULL</center> <br />
|Can be used to distinguish multiple grades for an activity <br />
|-<br />
|iteminfo <br />
|text <br />
|<center>NULL</center> <br />
|Info and notes about this item XXX <br />
|-<br />
|'''idnumber'''<br />
|varchar(255) <br />
|<center>NULL</center> <br />
|Arbitrary idnumber provided by the module responsible (optional and course unique)<br />
|-<br />
|calculation <br />
|text<br />
|<center>NULL</center> <br />
|Spreadsheet-type formula used to process the raw grades into final grades<br />
|-<br />
|'''gradetype''' <br />
|int(4) <br />
|<center>1</center> <br />
|0 = none, 1 = value, 2 = scale, 3 = text <br />
|-<br />
|grademax <br />
|float(10,5) <br />
|<center>100</center> <br />
|What is the maximum allowable grade? <br />
|-<br />
|grademin <br />
|float(10,5) <br />
|<center>0</center> <br />
|What is the minimum allowable grade? <br />
|-<br />
|'''scaleid''' <br />
|int(10) <br />
|<center>NULL</center> <br />
|If this grade is based on a scale, which one is it? <br />
|-<br />
|'''outcomeid''' <br />
|int(10) <br />
|<center>NULL</center> <br />
|If this is outcome item, which outcome is it? <br />
|-<br />
|gradepass<br />
|float(10,5) <br />
|<center>0</center> <br />
|What grade is needed to pass? grademin <= gradepass <= grademax<br />
|-<br />
|multfactor <br />
|float(10,5) <br />
|<center>1.0</center> <br />
|Multiply all raw grades from activities by this <br />
|-<br />
|plusfactor <br />
|float(10,5) <br />
|<center>0.0</center> <br />
|Add this to all raw grades from activities by this <br />
|-<br />
|aggregationcoef <br />
|float(10,5) <br />
|<center>0.0</center> <br />
|Weight applied to all grades in this grade item during aggregation with other grade items.<br />
|-<br />
|sortorder <br />
|int(10) <br />
|<center>0</center> <br />
|Sorting order of the columns (pre-order walk of the grading tree)<br />
|-<br />
|display<br />
|int(10) <br />
|<center>0</center> <br />
|Display as real grades, percentages (in reference to the minimum and maximum grades) or letters (A, B, C etc..), or course default (0)<br />
|-<br />
|hidden <br />
|int(10) <br />
|<center>0</center> <br />
|1 is hidden, 1 is hide always, > 1 is a date to hide until (prevents viewing of all user grades) <br />
|-<br />
|'''locked'''<br />
|int(10) <br />
|<center>0</center> <br />
|0 is not locked, > 0 is a date when was item locked (no final grade or grade_item updates possible)<br />
|-<br />
|'''locktime'''<br />
|int(10) <br />
|<center>0</center> <br />
|0 no auto locking, > 0 is a date to lock grade item and final grades after automatically <br />
|-<br />
|deleted <br />
|int(10) <br />
|<center>0</center> <br />
|1 means the associated module instance has been deleted<br />
|-<br />
|'''needsupdate'''<br />
|int(10) <br />
|<center>0</center> <br />
|If this flag is set, then the whole column will be recalculated. If set in course item, some other item needs recalculation. Calculated and category items are recalculated together with any other items.<br />
|-<br />
|timecreated <br />
|int(10)<br />
|<br />
|The first time this grade_item was created<br />
|-<br />
|timemodified <br />
|int(10)<br />
|<br />
|The last time this grade_item was modified<br />
|}<br />
<br />
=== grade_categories ===<br />
<br />
This table keeps information about categories, used for grouping items. An associated grade_item will be maintained for each category to store the aggregate data.<br />
<br />
{| border="1" cellpadding="2" cellspacing="0"<br />
|'''Field''' <br />
|'''Type''' <br />
|'''Default''' <br />
|'''Info''' <br />
|-<br />
|'''id''' <br />
|int(10) <br />
|<br />
|autoincrementing <br />
|-<br />
|'''courseid''' <br />
|int(10) <br />
|<br />
|The course this grade category is part of <br />
|-<br />
|'''parent''' <br />
|int(10) <br />
|<center>NULL</center> <br />
|Parent grade_category (hierarchical)<br />
|-<br />
|depth<br />
|int(10) <br />
|<center>0</center> <br />
|How deep is this category from the highest level (1,2,3)<br />
|-<br />
|path<br />
|varchar(255) <br />
| <br />
|Shows the path as /1/2/3/ <br />
|-<br />
|fullname <br />
|varchar(255) <br />
|<br />
|The name of this grade category <br />
|-<br />
|aggregation <br />
|int(10) <br />
|<center>0</center> <br />
|A constant pointing to one of the predefined aggregation strategies (none, mean,median,sum, etc) <br />
|-<br />
|keephigh <br />
|int(10) <br />
|<center>0</center> <br />
|Keep only the X highest items <br />
|-<br />
|droplow <br />
|int(10) <br />
|<center>0</center> <br />
|Drop the X lowest items <br />
|-<br />
|aggregateonlygraded<br />
|int(1) <br />
|<center>0</center> <br />
|Aggregate only existing grades <br />
|-<br />
|aggregateoutcomes<br />
|int(1) <br />
|<center>0</center> <br />
|Aggregate otcomes together with normal items <br />
|-<br />
|aggregatesubcats<br />
|int(1) <br />
|<center>0</center> <br />
|Aggregate only items placed directly in category or all items in subcategories excluding the subcategory totals <br />
|-<br />
|timecreated<br />
|int(10) <br />
|<br />
|The first time this grade_category was created<br />
|-<br />
|timemodified <br />
|int(10) <br />
|<br />
|The last time this grade_category was modified<br />
|}<br />
<br />
=== grade_grades ===<br />
<br />
This table keeps individual grades for each user and each item. The raw grade is exactly as imported or submitted by modules. The rawgrademax/min and rawscaleid are stored here to record the values at the time the grade was stored, because teachers might change this for an activity! All the results are normalised/resampled/calculated for the finalgrade, which is relative to the max/min/scaleid values stored in the grade_item. The finalgrade field is effectively a cache and values are rebuilt whenever raw values or the grade_item changes.<br />
<br />
Note that the finalgrade for a scale-based item may be non-integer! It needs to be rounded on display.<br />
<br />
{| border="1" cellpadding="2" cellspacing="0"<br />
|'''Field''' <br />
|'''Type''' <br />
|'''Default''' <br />
|'''Info''' <br />
|-<br />
|'''id''' <br />
|int(10) <br />
|<br />
|autoincrementing <br />
|-<br />
|'''itemid''' <br />
|int(10) <br />
|<br />
|The item this grade belongs to <br />
|-<br />
|'''userid''' <br />
|int(10) <br />
|<br />
|The user who this grade is for <br />
|-<br />
|rawgrade<br />
|float(11,10) <br />
|<center>NULL</center> <br />
|The raw grade that came into the system<br />
|-<br />
|rawgrademax <br />
|float(11,10) <br />
|<center>100</center> <br />
|The maximum allowable grade when this was created <br />
|-<br />
|rawgrademin <br />
|float(11,10) <br />
|<center>0</center> <br />
|The minimum allowable grade when this was created <br />
|-<br />
|'''rawscaleid''' <br />
|int(10) <br />
|<center>NULL</center> <br />
|If this grade is based on a scale, which one was it? <br />
|-<br />
|'''usermodified'''<br />
|int(10) <br />
|<center>NULL</center> <br />
|the userid of the person who last modified the raw grade value<br />
|-<br />
|finalgrade<br />
|float(11,10) <br />
|<center>NULL</center> <br />
|The final grade (cached) after all calculations are made. Overriden grades are also stored here.<br />
|- <br />
|hidden <br />
|int(10) <br />
|<center>0</center> <br />
|0 is not hidden, 1 is hide always, > 1 is a date to hide until <br />
|-<br />
|'''locked'''<br />
|int(10) <br />
|<center>0</center> <br />
|0 is not locked, > 0 when was the grade locked<br />
|-<br />
|'''locktime'''<br />
|int(10) <br />
|<center>0</center> <br />
|0 is never, > 0 is a date to lock the final grade after automatically<br />
|-<br />
|exported <br />
|int(10) <br />
|<center>0</center> <br />
|0 is not exported, > 0 is the last exported date <br />
|-<br />
|excluded <br />
|int(10) <br />
|<center>0</center> <br />
|grade excluded from aggregation, > 0 is the last exported date <br />
|-<br />
|overridden <br />
|int(10) <br />
|<center>0</center> <br />
|0 is not overridden, > 0 is the last overridden date <br />
|-<br />
|feedback <br />
|text <br />
|<center>NULL</center> <br />
|Manual feedback from the teacher. Could be a code like 'mi'. <br />
|-<br />
|feedbackformat<br />
|int(10)<br />
|<center>0</center> <br />
|Text format for feedback<br />
|-<br />
|information <br />
|text <br />
|<center>NULL</center> <br />
|not sued yet (Further information like forum rating distribution 4/5/7/0/1 ?)<br />
|-<br />
|informationformat<br />
|int(10)<br />
|<center>0</center> <br />
|Text format for information<br />
|-<br />
|timecreated<br />
|int(10) <br />
|<br />
|temporary hack - the date of submission in activity if any, new field expected in 2.0<br />
|-<br />
|timemodified<br />
|int(10) <br />
|<br />
|temporary hack - the date of grading in activity or date of manual grading in gradebook, new field expected in 2.0<br />
|}<br />
<br />
=== grade_outcomes ===<br />
<br />
This table describes the outcomes used in the system. An outcome is a statement tied to a rubric scale from low to high, such as “Not met, Borderline, Met” (stored as 0,1 or 2). For more info about these see [[Development:Outcomes]].<br />
<br />
{| border="1" cellpadding="2" cellspacing="0"<br />
|'''Field''' <br />
|'''Type''' <br />
|'''Default''' <br />
|'''Info''' <br />
<br />
|-<br />
|'''id''' <br />
|int(10) <br />
|<br />
|autoincrementing <br />
<br />
|-<br />
|'''courseid''' <br />
|int(10) <br />
|<center>NULL</center> <br />
|Mostly these are defined site wide ie NULL <br />
<br />
|-<br />
|shortname <br />
|varchar(255) <br />
|<br />
|The short name or code for this outcome statement <br />
<br />
|-<br />
|fullname <br />
|text <br />
|<br />
|The full description of the outcome (usually 1 sentence) <br />
<br />
|-<br />
|'''scaleid''' <br />
|int(10) <br />
|<br />
|The recommended scale for this outcome. <br />
|-<br />
|description <br />
|text <br />
|<center>NULL</center> <br />
|The full description of the outcome (usually 1 sentence) <br />
|-<br />
|timecreated<br />
|int(10) <br />
|<br />
|the time this outcome was first created <br />
<br />
|-<br />
|timemodified<br />
|int(10) <br />
|<br />
|the time this outcome was last updated <br />
<br />
|-<br />
|'''usermodified'''<br />
|int(10) <br />
|<center>NULL</center> <br />
|the userid of the person who last modified this outcome<br />
|}<br />
<br />
=== grade_outcomes_courses ===<br />
An intersection table used to make standard outcomes available to courses.<br />
<br />
{| border="1" cellpadding="2" cellspacing="0"<br />
|'''Field''' <br />
|'''Type''' <br />
|'''Default''' <br />
|'''Info''' <br />
<br />
|-<br />
|'''id''' <br />
|int(10) <br />
|<br />
|autoincrementing <br />
<br />
|-<br />
|'''courseid'''<br />
|int(10)<br />
|<br />
|The id of the course being assigned the outcome<br />
<br />
|-<br />
|'''outcomeid''' <br />
|int(10) <br />
|<br />
|The id of the outcome being assigned to the course<br />
|}<br />
<br />
=== grade_import_newitem ===<br />
<br />
{| border="1" cellpadding="2" cellspacing="0"<br />
|'''Field''' <br />
|'''Type''' <br />
|'''Default''' <br />
|'''Info''' <br />
<br />
|-<br />
|'''id''' <br />
|int(10) <br />
|<br />
|autoincrementing <br />
<br />
|-<br />
|itemname<br />
|varchar(255)<br />
|<br />
|*TODO* Document<br />
<br />
|-<br />
|importcode<br />
|int(12) <br />
|<br />
|*TODO* Document <br />
|}<br />
<br />
=== grade_import_values ===<br />
<br />
{| border="1" cellpadding="2" cellspacing="0"<br />
|'''Field''' <br />
|'''Type''' <br />
|'''Default''' <br />
|'''Info''' <br />
<br />
|-<br />
|'''id''' <br />
|int(10) <br />
|<br />
|autoincrementing <br />
<br />
|-<br />
|'''itemid''' <br />
|int(10) <br />
|NULL<br />
|*TODO* Document <br />
<br />
|-<br />
|newgradeitem<br />
|int(10)<br />
|NULL<br />
|*TODO* Document<br />
<br />
|-<br />
|'''userid''' <br />
|int(10) <br />
|<br />
|*TODO* Document <br />
<br />
|-<br />
|finalgrade<br />
|float(10,5) <br />
|NULL<br />
|*TODO* Document <br />
<br />
|-<br />
|feedback<br />
|text<br />
|NULL<br />
|*TODO* Document <br />
<br />
|-<br />
|importcode<br />
|int(12) <br />
|<br />
|*TODO* Document <br />
|}<br />
<br />
=== History tables ===<br />
<br />
These table keep track of changes to most of the grade tables. Using these it should be possible to reconstruct the grades at any point in time in the past, or to audit grade changes over time. It should be quicker to use these tables for that, rather than storing this information in the main Moodle log. The following tables are set up for that purpose:<br />
<br />
#grade_categories_history<br />
#grade_grades_history<br />
#grade_items_history<br />
#grade_outcomes_history<br />
<br />
Each of them has exactly the same DB structure as their matching table (e.g. grade_categories), with 3 extra fields:<br />
<br />
<br />
<br />
{| border="1" cellpadding="2" cellspacing="0"<br />
|'''Field''' <br />
|'''Type''' <br />
|'''Default''' <br />
|'''Info''' <br />
<br />
|-<br />
|action<br />
|int(10) <br />
|0<br />
|The action that lead to the change being recorded (insert, update, delete)<br />
<br />
|-<br />
|'''oldid''' <br />
|int(10) <br />
|<br />
|The id of the record being changed or inserted (PK of the main table, not the history table) <br />
<br />
|-<br />
|source<br />
|varchar(255)<br />
|NULL<br />
|The module from which the action originated <br />
|}<br />
<br />
=== grade_letters ===<br />
<br />
{| border="1" cellpadding="2" cellspacing="0"<br />
|'''Field''' <br />
|'''Type''' <br />
|'''Default''' <br />
|'''Info''' <br />
<br />
|-<br />
|'''id''' <br />
|int(10) <br />
|<br />
|autoincrementing <br />
<br />
|-<br />
|contextid<br />
|int(10)<br />
|<br />
|What contextid does this letter apply to (from levels CONTEXT_SYSTEM, CONTEXT_COURSECAT or CONTEXT_COURSE)<br />
<br />
|-<br />
|lowerboundary<br />
|float(10,5) <br />
|<br />
|The lower boundary of the letter. Its upper boundary is the lower boundary of the next highest letter, unless there is none above, in which case it's grademax for that grade_item.<br />
<br />
|-<br />
|letter<br />
|varchar(255) <br />
|<br />
|The display value of the letter. Can be any character or string of characters (OK, A, 10% etc..) <br />
|}<br />
<br />
== Overview of module communication ==<br />
<br />
Modules usually store raw grades internally and pass them into gradebook every time they change. Gradebook may also request activities to resend the grades. <br />
<br />
The gradebook is designed to be as separate as possible from the code of activities - modules do not read grade tables or use internal gradebook API. <br />
<br />
Originally it was planned to use new events API, but in the end it was decided to use minimal API consisting of several function in lib/gradelib.php and each mod/xxx/lib.php<br />
<br />
=== Backward compatibility with Moodle 1.8 and earlier ===<br />
<br />
Function grade_grab_legacy_grades($courseid) may be used to request transfer of grades from legacy or 3rd party activities which were not yet converted to new grade API. This function is not called automatically.<br />
<br />
Modules are responsible to push existing grades into gradebook during upgrade.<br />
<br />
==API for communication with modules/blocks==<br />
<br />
Modules may use only functions from lib/gradelib.php which are marked as public. This API may be extended in later 1.9.x release. Activities should access/update only own grades.<br />
<br />
===grade_get_grades()===<br />
<br />
grade_get_grades($courseid, $itemtype, $itemmodule, $iteminstance, $userid_or_ids=0)<br />
<br />
Returns grading information for given activity - optionally with users grades. Manual, course or category items can not be queried.<br />
<br />
===grade_get_outcomes()===<br />
<br />
grade_get_outcomes($courseid, $itemtype, $itemmodule, $iteminstance,$userid=0)<br />
<br />
Returns list of outcomes used in course together with current outcomes for this user.<br />
<br />
===grade_is_locked()===<br />
<br />
grade_is_locked($courseid, $itemtype, $itemmodule, $iteminstance, $itemnumber, $userid=NULL)<br />
<br />
This function will tell a module whether a grade (or grade_item if $userid is not given) is currently locked or not. If it's locked to the current user then the module can print a nice message or prevent editing in the module. If no $userid is given, the method will always return the grade_item's locked state. If a $userid is given, the method will first check the grade_item's locked state (the column). If it is locked, the method will return true no matter the locked state of the specific grade being checked. If unlocked, it will return the locked state of the specific grade.<br />
([http://moodle.org/mod/forum/discuss.php?d=69223#p311329 info])<br />
<br />
===grade_update()===<br />
<br />
grade_update($source, $courseid, $itemtype, $itemmodule, $iteminstance, $itemnumber, $grades=NULL, $itemdetails=NULL)<br />
<br />
Submit new or update grade; update/create grade_item definition. Grade must have userid specified, rawgrade and feedback with format are optional. rawgrade NULL means 'Not graded', missing property or key means do not change existing. Only following grade item properties can be changed 'itemname', 'idnumber', 'gradetype', 'grademax', 'grademin', 'scaleid', 'multfactor', 'plusfactor', 'deleted'.<br />
<br />
===grade_update_outcomes()===<br />
<br />
grade_update_outcomes($source, $courseid, $itemtype, $itemmodule, $iteminstance, $userid, $data)<br />
<br />
Updates outcomes of a given user. Manual outcomes cannot be updated.<br />
<br />
== Private gradebook API ==<br />
Private API is used by gradebook plugins and core Moodle code, it may change in 2.0. Most of the interesting classes and functions are in lib/gradelib.php, grade/lib.php and grade/report/lib.php.<br />
<br />
The following 3 functions are all in /lib/gradelib.php<br />
<br />
===grade_regrade_final_grades()===<br />
<br />
grade_regrade_final_grades($courseid=NULL, $userid=NULL, $updated_item=NULL)<br />
<br />
Updates all grade_grades->finalgrade records for each grade_item matching the given attributes. The search is further restricted, so that only grade_items that have needs_update == true or that use calculation are retrieved and used for the update. The function returns the number of grade_items updated (NOT the same as the number of grades_grades updated!).<br />
<br />
===grade_verify_idnumber()===<br />
<br />
grade_verify_idnumber($idnumber, $grade_item = null, $cm = null, $gradeitem)<br />
<br />
Verify new value of idnumber - checks for uniqueness of new idnubmers, existing are kept intact.<br />
<br />
===remove_course_grades()===<br />
<br />
remove_course_grades($courseid, $showfeedback)<br />
<br />
Remove all grade related course data - history is kept<br />
<br />
<br />
TODO: add description of the other methods and classes + simple usage examples + querylib.php description<br />
<br />
== Dealing with multiple grades ==<br />
<br />
Modules usually produce only one grade item per activity. Optionally one or more outcomes may be attached to activities.<br />
<br />
Some activities may need to aggregate multiple ratings or attempts before sending them into the gradebook. Activities can not send variable number of items.<br />
<br />
If the gradebook receives multiple grade items from a module, then they are automatically grouped together in a unique grade category (with the same name as the module instance). See [[Development:Outcomes]] for more details.<br />
<br />
TODO: this may still be changed<br />
<br />
== Calculated grade items ==<br />
<br />
Categories or manual items maybe calculated using spreadsheet-like formulas. Formulas may reference other items from the same course only using Id numbers in double square brackets.<br />
<br />
eg: <nowiki>= MEAN([[quiz121]], [[quizend]]) + [[assignmentAXC]] + 20.0</nowiki><br />
<br />
== Regrading / updating of final grades ==<br />
<br />
TODO: describe needsupdate flag and incremental updates<br />
<br />
== Adjustment of raw grades ==<br />
Grade_item contains optional rules for adjusting the raw grade before it is cached into a final grade. These rules are processed BEFORE the calculation discussed above. Scale is never changed. Multfactor and plusfactor may be used to alter raw grades coming from activities, but it is recommended to use formulas instead.<br />
<br />
== Displaying the grades to ordinary participants ==<br />
<br />
The module takes responsibility for displaying grades within the module (to a student, say). It is recommended to use the real final grades obtained using grade_get_grades() functionBecause guidebook might force hiding, override grade, etc.<br />
<br />
For full display of grades in a whole course say, the student uses the same link as teachers use to access the gradebook. However, due to their different permissions they will only have access to specific reports. By default this is the ''User report'' report which only shows their own grades and has very few configuration options.<br />
<br />
== Locked grades ==<br />
<br />
Both whole columns and individual grades can be locked in the gradebook, via the ''locked'' field. Teachers may want to do this to prevent further changes from the modules, or from other teachers. When a grade is locked, any changes that might affect that grade are ignored. When the graded is unlocked, activities are asked to resend the latest grades.<br />
<br />
In the main GUIs the lock toggling will be achieved by clicking on a little padlock icon beside each entry or column.<br />
<br />
There is also an option to lock grade or item after some specified date.<br />
<br />
== Overridden grades ==<br />
<br />
Grades can be manually modified (overridden) in the gradebook. When this is done the entered value is always used instead of the aggregated, calculated or activity grade.<br />
<br />
Once grades have been overriden in the gradebook they become read only in the original module. The module should provide a visual indication as to why the grade cannot be modified.<br />
<br />
The need to improve how the module expresses that a grade has been overridden will be reduced by the new [https://docs.moodle.org/en/Development:Grading_interface_2.0 grading interface]<br />
<br />
== Hidden grades and categories ==<br />
<br />
Grades and categories can be hidden in the gradebook or the "categories and items" screen. When a category is hidden all the grade items within it are automatically hidden as well. When a category is un-hidden then all the grade items within it are un-hidden.<br />
<br />
The teacher always sees totals calculated from all relevant items (hidden or un-hidden)<br />
<br />
(Features below were added in 1.9.8 and 2.0)<br />
<br />
When a grade is shown its parent category will also be shown if it was hidden. MDL-21367<br />
<br />
The teacher decides what ordinary users can see in the case of totals that include hidden grades (MDL-21218, in 1.9.8 and 2.0). The user and overview report each have a setting to choose between:<br />
<br />
# Hide any totals that are dependent on a hidden item (show a hyphen there) [DEFAULT]<br />
# Display totals excluding the hidden items<br />
# Display full totals including the hidden items (may allow students to back-calculate hidden grades)<br />
<br />
== Logging ==<br />
<br />
All grading related changes maybe logged in history tables.<br />
<br />
== Security Issues ==<br />
<br />
For security an option to force SSL for the gradebook might be good.<br />
<br />
==Overall grade==<br />
<br />
Each course has exactly one course grade item. It may be used for this purpose now. Other course completion criteria will be implemented in 2.0.<br />
<br />
== Report plugins ==<br />
All the main interface of the gradebook are implemented as report plugins. Each plugin is fully responsible for page layout, there are some handy functions in grade/lib.php. They can even define their own capabilities and extra tables if the core tables are not enough, as they'll have a full /grade/report/xxxx/db directory.<br />
<br />
Each report defines one capability to allow people to see that report, so that admins have control over who can see what reports. For example, the participant interface can be a totally separate report plugin.<br />
<br />
This allows for the widest flexibility and safety in how grades are presented.<br />
<br />
=== Default teacher interface ===<br />
This interface will be what teachers see by default, and will subsume everything the current interface (in Moodle 1.8) does.<br />
<br />
Some snippets of functionality:<br />
{{Moodle 1.9}}<br />
Overall it's a grid, with participant names down one side and grade items along the top. <br />
<br />
Columns will be able to be collapsed together by grouping them into categories. Grades for categories can be calculated via various means. <br />
<br />
“Eye-cons” on the columns and checkboxes by every grade (this bit possibly controlled with a switch) allow hiding by category, by column, by individual grade.<br />
<br />
Textual notes can be added to each grade for more info. These show up to participants as well.<br />
<br />
A groups menu allows the teacher to switch between showing EACH of the groups they have access to, or ALL the groups they have access to.<br />
<br />
All grade items will link to modulepath/grade.php?id=44 which will work out what the current person should be allowed to see and either redirect them to the correct page or just show them immediately. This copes with situations like the quiz, say, where we want editing teachers to go to the detailed reports there while participants just see their own grade or whatever the quiz is set to show.<br />
<br />
User preference to SWITCH between showing raw grades, percentage grades, or both, or grade letters (A/B/C etc). <br />
<br />
Settings for grade letters not only define the transformation from percentage to grades, but also the transformation from letters to grades (in case the teacher edits some of the letter grades).<br />
<br />
Categories are shown above the headings for each column. Clicking for more info on a category will just show the category with a summary column showing total/average for just that category (PLUS the summary column for the whole course).<br />
<br />
All columns should be sortable up/down.<br />
<br />
At the bottom of each column is a row with the mean course score. If in groups mode, then add ANOTHER row with just the group mean. Add the number of grades used in brackets. eg 56% (11). When the report is paged, these means are still for the whole course/group (not the page!)<br />
<br />
{{Moodle 2.0}}<br />
<br />
Teachers can type “straight into” the grid using AJAX or fallback to forms. No popup menus for values.<br />
<br />
Later on we can support customisable shorthand codes to make data entry quick (eg type 'ab' for absent, or 'nge' for not good enough).<br />
<br />
See [http://test.moodle.com/grade/report/grader/index.php?id=2 the test site] for a live demo of this report.<br />
<br />
=== Default participant interface ===<br />
This interface will be what participants see by default:<br />
<br />
Some snippets of functionality:<br />
<br />
*Invert the grid to show one item per row, with the total/average at the bottom.<br />
*Use second/third columns to show categories.<br />
*Include ranking score in another column.<br />
*Show feedback<br />
*Show percentage<br />
*No editing functionality.<br />
<br />
See [http://test.moodle.com/grade/report/user/index.php?id=2 the test site] for a live demo of this report.<br />
<br />
=== Outcomes report ===<br />
This simple informational report displays all the outcomes used by the course, with the following information:<br />
<br />
*Outcome name<br />
*Overall average: If the outcome is used by more than one activity, this shows you the mean across all these activities in the current course<br />
*Site-wide: Yes or No: A site-wide outcome is automatically made available to all courses.<br />
*Activities: A list of links to the activities in the current course that use each outcome. One row per activity (table splits here)<br />
*Average: For each activity using the outcome, the average score is shown.<br />
*Number of grades: For each activity using the outcome, the number of grades is shown (non-graded participants are ignored)<br />
<br />
See [http://test.moodle.com/grade/report/outcomes/index.php?id=2 the test site] for a live demo of this report.<br />
<br />
=== Overview report ===<br />
Another basic report, showing a participant's course averages in each of the courses in which s/he has received grades.<br />
<br />
See [http://test.moodle.com/grade/report/overview/index.php the test site] for a live demo of this report.<br />
<br />
== Export plugins ==<br />
<br />
The API for these is extremely simple. Each export plugin should occupy a directory under /grade/export/xyz and needs to provide only an index.php file as a the primary interface. This file just accepts a 'courseid' parameter.<br />
<br />
== Import plugins ==<br />
<br />
Each import plugin should occupy a directory under /grade/import/xyz and needs to provide only an index.php file as a the primary interface. This file just accepts a 'courseid' parameter.<br />
<br />
The index.php will show an interface for further options and selections.<br />
<br />
Import plugin must validate data before starting the import operation, if some parts of import fail the user must be notified.<br />
<br />
Some sample import plugins are:<br />
<br />
===Import from CSV===<br />
<br />
Accepts an upload of (or URL to) a CSV file. Multiple options describe how to process the file, which columns to add etc. The imported grades always override current grades.<br />
<br />
===Import from XML===<br />
<br />
Accepts an upload of (or URL to) an XML file with this kind of format (from OU). <br />
<br />
<results batch="[someuniqueimportnumber]"><br />
<result><br />
<state>['new' or 'regrade']</state><br />
<assignment>[idnumber]</assignment><br />
<student>[studentid]</student><br />
<score>[score]</score><br />
</result><br />
<result><br />
<state>['new' or 'regrade']</state><br />
<assignment>[idnumber]</assignment><br />
<student>[studentid]</student><br />
<score>[score]</score><br />
</result><br />
[...]<br />
</results><br />
<br />
== Capabilities and Permissions ==<br />
<br />
* moodle/grade:view - view own grades or grades of other user if used in CONTEXT_USER<br />
<br />
* moodle/grade:viewall - view grades of all users<br />
<br />
* moodle/grade:viewhidden - see grades that are marked as hidden for the owner<br />
<br />
* moodle/grade:hide - be able to hide/unhide cells, items or categories<br />
<br />
* moodle/grade:lock - be able to lock cells, items or categories<br />
<br />
* moodle/grade:unlock - be able to unlock cells, items or categories<br />
<br />
* moodle/grade:manage - manage grade items and categories in gradebook (create, edit, lock, hide, delete, etc.)<br />
<br />
* moodle/grade:import - general import grades, requires separate permission for each plugin<br />
<br />
* moodle/grade:export - export grades, requires separate permission for each plugin<br />
<br />
* gradereport/grader:view - can view the grader report<br />
<br />
* gradeimport/csv:view - can view/use the csv import plugin<br />
<br />
* gradeexport/csv:view - can view/use the csv export plugin<br />
<br />
* moodle:site/accessallgroups<br />
<br />
== Development Tasks and Tracking ==<br />
<br />
For details of 1.9 development see [http://tracker.moodle.org/browse/MDL-9137 MDL-9137]<br />
<br />
For details of 2.0 development see [https://docs.moodle.org/en/Development:Gradebook_improvements Gradebook_imporovements] and [http://tracker.moodle.org/browse/MDL-19131 MDL-19131]<br />
<br />
==Updating module code==<br />
Module authors must implement new gradebook API and add upgrade code for migration of old grades into new gradebook. Fortunately the needed changes are not big.<br />
<br />
Steps:<br />
*add xxx_update_grades() function into mod/xxx/lib.php<br />
*add xxx_grade_item_update() function into mod/xxx/lib.php<br />
*patch xxx_update_instance(), xxx_add_instance() and xxx_delete_instance() to call xxx_grade_item_update()<br />
*patch all places of code that change grade values to call xxx_update_grades()<br />
*patch code that displays grades to students to use final grades from the gradebook<br />
<br />
There are many examples in official modules, assignment has the most advanced implementation.<br />
<br />
== Ideas for the future ==<br />
{{Moodle 2.0}} {{Moodle 2.1}}<br />
See [[Development:Gradebook_improvements]] and MDL-25423 for details of planned future enhancements<br />
<br />
*option to aggregate including/excluding hidden grades - needs db changes<br />
*option to rollback all changes during import operation if anything fails<br />
*performance improvements<br />
*conditional activities<br />
*course completion criteria<br />
*better public API for modules<br />
*better API for gradebook plugins<br />
*better state tracking in export plugins<br />
*ajax reports<br />
*specialised reports<br />
*submission and marking date tracking db changes<br />
*calculation formula improvements<br />
*historical views<br />
*individual graph of grades (time vs %). Bar graph, lineal graph. Add (or not) the maximum posible; line of 0 (=minimum), 25, 50 (=median), 75 and 100 (=max) percentils of the group.<br />
*<br />
<br />
== See also ==<br />
<br />
* [http://moodle.org/mod/forum/discuss.php?d=69223&mode=3 Gradebook Development ideas] forum discussion<br />
* Using Moodle [http://moodle.org/mod/forum/discuss.php?d=51107 New gradebook for Moodle] forum discussion<br />
* [[Development:Gradebook Report Tutorial]]<br />
<br />
[[Category:Developer|Grades]]<br />
[[Category:Grades]]</div>Andyjdavishttps://docs.moodle.org/20/en/index.php?title=Development:Grades&diff=79039Development:Grades2010-12-10T04:00:56Z<p>Andyjdavis: /* grade_is_locked() */</p>
<hr />
<div>{{Work in progress}}<br />
<br />
== Executive Summary ==<br />
<br />
This document primarily describes the current workings of the gradebook. For more detailed information about current gradebook development see [[Development:Gradebook_improvements]]<br />
<br />
The gradebook mechanisms must be rebuilt to:<br />
<br />
# '''Improve performance and scalability''' - All grades from throughout the system will be pushed to a central system of tables. This means reports based on grades can be generated much faster, and the gradebook has ultimate control over the content.<br />
# '''Improve flexibility''' - All aspects of the new gradebook will use simple plugin structures, namely: exports, imports and displays/reports. It is expected that the community will be very active in producing [[Development:Gradebook Report Tutorial |special-purpose reports]] analysing the basic grade data in new ways, for example, or writing plugins to transfer grades to student information systems.<br />
# '''Allow rubrics for outcomes (aka standards,competencies,goals)''' - As well as numerical grades, each grading item can consist of a number of scores made on a rubric against a standard outcome statement. These can be automatically converted to a numerical grade if desired or just shown as is.<br />
# '''Allow arbitrary columns and derived columns''' - Arbitrary columns of data can be added (either manually or via import). Columns can also be automatically filled based on formulas.<br />
# '''Implement limited public API''' - Activities may use this API to send grades/outcomes to gradebook and find out the final grades.<br />
<br />
== Glossary ==<br />
<br />
Here are some terms used in the gradebook, both in the development and the user interface. Using these terms in discussions about the gradebook will help to reduce confusion.<br />
<br />
{| class="nicetable"<br />
!Term<br />
!Definition<br />
|-<br />
|Activity<br />
|An instance of an activity module [[Category:Modules|Module]] (e.g. a single quiz, assignment etc...)<br />
|-<br />
|Calculation<br />
|A formula used to calculate grades, based (optionally) on other grade items. Not the same as [[Calculated_question_type|Calculated question types]].<br />
|-<br />
|Category<br />
|A set of Grade Items. A Category also has its own aggregated Grade which is calculated from its Grade Items. There is no limit to the level of nesting of Categories (a Category may belong to another Category). However, each Grade Item may belong to only one Category. <br />
|-<br />
|Course completion<br />
|The concept of meeting certain criteria for completing a course. In the context of the gradebook, this means a set of grades that must be reached, or a number of outcomes/competencies to complete/master.<br />
|-<br />
|Grade<br />
|A Grade is a single assessment. It may be a number or an item on a scale (possibly tied to an Outcome). Raw grade value is the numerical or scale grade from activity. Final grade is the grade reported in gradebook.<br />
|-<br />
|[[Gradebook|Gradebook]]<br />
|A central location in Moodle where students' Grades are stored and displayed. Teachers can keep track of their students' progress and organise which set of Grades their students will be able to see. Students see their own Grades.<br />
|-<br />
|Grade Item<br />
|A "column" of Grades. It can be created from a specific Activity or other module, calculated from other Grade Items, or entered manually.<br />
|-<br />
|[[Development:Grades#Locked_grades|Grade Locks]]<br />
|See linked section of this page<br />
|-<br />
|History<br />
|The gradebook has its own type of log, which keeps a History of all changes made to grades.<br />
|-<br />
|[[Development:Outcomes|Outcome]]<br />
|[[Development:Outcomes|Outcomes]] are specific descriptions of what a person is expected to be able to do or understand at the completion of an activity or course. An activity might have more than one outcome, and each may have a grade against it (usually on a scale). Other terms for Outcomes are ''Competencies'' and ''Goals''. See some [[Development:Outcomes_examples|Examples]].<br />
|-<br />
|[[Scales|Scale]]<br />
|A scale is a set of responses from which the teacher can choose one. eg Very cool, Cool, Fairly cool, Not very cool, Not cool<br />
|-<br />
|Letter Grades<br />
|Special representation of grade values similar to scales. Letters are configured in course contexts or above and are defined by lower boundary. eg A (above 90 %), B (above 80 %), C (above 70 %), D (above 50 %), F (above 0 %)<br />
<br />
|}<br />
<br />
== Database structures ==<br />
=== grade_items ===<br />
<br />
This table keeps information about gradeable items (ie columns). If an activity (eg an assignment or quiz) has multiple grade_items associated with it (eg several outcomes and numerical grade), then there will be a corresponding multiple number of rows in this table.<br />
<br />
idnumber is a tag unique inside a course identifying the grade item, useful for identifying data in exports and for referring to the grade item in calculations. It is the same as the idnumber in course_modules.<br />
<br />
<br />
{| border="1" cellpadding="2" cellspacing="0"<br />
|'''Field''' <br />
|'''Type''' <br />
|'''Default''' <br />
|'''Info''' <br />
|-<br />
|'''id''' <br />
|int(10) <br />
|<br />
|autoincrementing <br />
|-<br />
|'''courseid''' <br />
|int(10) <br />
|<br />
|The course this item is part of <br />
|-<br />
|'''categoryid''' <br />
|int(10) <br />
|<center>NULL</center> <br />
|the category group this item belongs to <br />
|-<br />
|itemname <br />
|varchar(255) <br />
|<center>NULL</center> <br />
|The name of this item (pushed in by the module or entered by user) <br />
|-<br />
|'''itemtype''' <br />
|varchar(30) <br />
|<br />
|'mod', 'blocks', 'manual', 'course', 'category' etc <br />
|-<br />
|itemmodule <br />
|varchar(30) <br />
|<center>NULL</center> <br />
|'forum', 'quiz', 'csv', etc <br />
|-<br />
|iteminstance <br />
|int(10) <br />
|<center>NULL</center> <br />
|id of the item module <br />
|-<br />
|itemnumber <br />
|int(10) <br />
|<center>NULL</center> <br />
|Can be used to distinguish multiple grades for an activity <br />
|-<br />
|iteminfo <br />
|text <br />
|<center>NULL</center> <br />
|Info and notes about this item XXX <br />
|-<br />
|'''idnumber'''<br />
|varchar(255) <br />
|<center>NULL</center> <br />
|Arbitrary idnumber provided by the module responsible (optional and course unique)<br />
|-<br />
|calculation <br />
|text<br />
|<center>NULL</center> <br />
|Spreadsheet-type formula used to process the raw grades into final grades<br />
|-<br />
|'''gradetype''' <br />
|int(4) <br />
|<center>1</center> <br />
|0 = none, 1 = value, 2 = scale, 3 = text <br />
|-<br />
|grademax <br />
|float(10,5) <br />
|<center>100</center> <br />
|What is the maximum allowable grade? <br />
|-<br />
|grademin <br />
|float(10,5) <br />
|<center>0</center> <br />
|What is the minimum allowable grade? <br />
|-<br />
|'''scaleid''' <br />
|int(10) <br />
|<center>NULL</center> <br />
|If this grade is based on a scale, which one is it? <br />
|-<br />
|'''outcomeid''' <br />
|int(10) <br />
|<center>NULL</center> <br />
|If this is outcome item, which outcome is it? <br />
|-<br />
|gradepass<br />
|float(10,5) <br />
|<center>0</center> <br />
|What grade is needed to pass? grademin <= gradepass <= grademax<br />
|-<br />
|multfactor <br />
|float(10,5) <br />
|<center>1.0</center> <br />
|Multiply all raw grades from activities by this <br />
|-<br />
|plusfactor <br />
|float(10,5) <br />
|<center>0.0</center> <br />
|Add this to all raw grades from activities by this <br />
|-<br />
|aggregationcoef <br />
|float(10,5) <br />
|<center>0.0</center> <br />
|Weight applied to all grades in this grade item during aggregation with other grade items.<br />
|-<br />
|sortorder <br />
|int(10) <br />
|<center>0</center> <br />
|Sorting order of the columns (pre-order walk of the grading tree)<br />
|-<br />
|display<br />
|int(10) <br />
|<center>0</center> <br />
|Display as real grades, percentages (in reference to the minimum and maximum grades) or letters (A, B, C etc..), or course default (0)<br />
|-<br />
|hidden <br />
|int(10) <br />
|<center>0</center> <br />
|1 is hidden, 1 is hide always, > 1 is a date to hide until (prevents viewing of all user grades) <br />
|-<br />
|'''locked'''<br />
|int(10) <br />
|<center>0</center> <br />
|0 is not locked, > 0 is a date when was item locked (no final grade or grade_item updates possible)<br />
|-<br />
|'''locktime'''<br />
|int(10) <br />
|<center>0</center> <br />
|0 no auto locking, > 0 is a date to lock grade item and final grades after automatically <br />
|-<br />
|deleted <br />
|int(10) <br />
|<center>0</center> <br />
|1 means the associated module instance has been deleted<br />
|-<br />
|'''needsupdate'''<br />
|int(10) <br />
|<center>0</center> <br />
|If this flag is set, then the whole column will be recalculated. If set in course item, some other item needs recalculation. Calculated and category items are recalculated together with any other items.<br />
|-<br />
|timecreated <br />
|int(10)<br />
|<br />
|The first time this grade_item was created<br />
|-<br />
|timemodified <br />
|int(10)<br />
|<br />
|The last time this grade_item was modified<br />
|}<br />
<br />
=== grade_categories ===<br />
<br />
This table keeps information about categories, used for grouping items. An associated grade_item will be maintained for each category to store the aggregate data.<br />
<br />
{| border="1" cellpadding="2" cellspacing="0"<br />
|'''Field''' <br />
|'''Type''' <br />
|'''Default''' <br />
|'''Info''' <br />
|-<br />
|'''id''' <br />
|int(10) <br />
|<br />
|autoincrementing <br />
|-<br />
|'''courseid''' <br />
|int(10) <br />
|<br />
|The course this grade category is part of <br />
|-<br />
|'''parent''' <br />
|int(10) <br />
|<center>NULL</center> <br />
|Parent grade_category (hierarchical)<br />
|-<br />
|depth<br />
|int(10) <br />
|<center>0</center> <br />
|How deep is this category from the highest level (1,2,3)<br />
|-<br />
|path<br />
|varchar(255) <br />
| <br />
|Shows the path as /1/2/3/ <br />
|-<br />
|fullname <br />
|varchar(255) <br />
|<br />
|The name of this grade category <br />
|-<br />
|aggregation <br />
|int(10) <br />
|<center>0</center> <br />
|A constant pointing to one of the predefined aggregation strategies (none, mean,median,sum, etc) <br />
|-<br />
|keephigh <br />
|int(10) <br />
|<center>0</center> <br />
|Keep only the X highest items <br />
|-<br />
|droplow <br />
|int(10) <br />
|<center>0</center> <br />
|Drop the X lowest items <br />
|-<br />
|aggregateonlygraded<br />
|int(1) <br />
|<center>0</center> <br />
|Aggregate only existing grades <br />
|-<br />
|aggregateoutcomes<br />
|int(1) <br />
|<center>0</center> <br />
|Aggregate otcomes together with normal items <br />
|-<br />
|aggregatesubcats<br />
|int(1) <br />
|<center>0</center> <br />
|Aggregate only items placed directly in category or all items in subcategories excluding the subcategory totals <br />
|-<br />
|timecreated<br />
|int(10) <br />
|<br />
|The first time this grade_category was created<br />
|-<br />
|timemodified <br />
|int(10) <br />
|<br />
|The last time this grade_category was modified<br />
|}<br />
<br />
=== grade_grades ===<br />
<br />
This table keeps individual grades for each user and each item. The raw grade is exactly as imported or submitted by modules. The rawgrademax/min and rawscaleid are stored here to record the values at the time the grade was stored, because teachers might change this for an activity! All the results are normalised/resampled/calculated for the finalgrade, which is relative to the max/min/scaleid values stored in the grade_item. The finalgrade field is effectively a cache and values are rebuilt whenever raw values or the grade_item changes.<br />
<br />
Note that the finalgrade for a scale-based item may be non-integer! It needs to be rounded on display.<br />
<br />
{| border="1" cellpadding="2" cellspacing="0"<br />
|'''Field''' <br />
|'''Type''' <br />
|'''Default''' <br />
|'''Info''' <br />
|-<br />
|'''id''' <br />
|int(10) <br />
|<br />
|autoincrementing <br />
|-<br />
|'''itemid''' <br />
|int(10) <br />
|<br />
|The item this grade belongs to <br />
|-<br />
|'''userid''' <br />
|int(10) <br />
|<br />
|The user who this grade is for <br />
|-<br />
|rawgrade<br />
|float(11,10) <br />
|<center>NULL</center> <br />
|The raw grade that came into the system<br />
|-<br />
|rawgrademax <br />
|float(11,10) <br />
|<center>100</center> <br />
|The maximum allowable grade when this was created <br />
|-<br />
|rawgrademin <br />
|float(11,10) <br />
|<center>0</center> <br />
|The minimum allowable grade when this was created <br />
|-<br />
|'''rawscaleid''' <br />
|int(10) <br />
|<center>NULL</center> <br />
|If this grade is based on a scale, which one was it? <br />
|-<br />
|'''usermodified'''<br />
|int(10) <br />
|<center>NULL</center> <br />
|the userid of the person who last modified the raw grade value<br />
|-<br />
|finalgrade<br />
|float(11,10) <br />
|<center>NULL</center> <br />
|The final grade (cached) after all calculations are made. Overriden grades are also stored here.<br />
|- <br />
|hidden <br />
|int(10) <br />
|<center>0</center> <br />
|0 is not hidden, 1 is hide always, > 1 is a date to hide until <br />
|-<br />
|'''locked'''<br />
|int(10) <br />
|<center>0</center> <br />
|0 is not locked, > 0 when was the grade locked<br />
|-<br />
|'''locktime'''<br />
|int(10) <br />
|<center>0</center> <br />
|0 is never, > 0 is a date to lock the final grade after automatically<br />
|-<br />
|exported <br />
|int(10) <br />
|<center>0</center> <br />
|0 is not exported, > 0 is the last exported date <br />
|-<br />
|excluded <br />
|int(10) <br />
|<center>0</center> <br />
|grade excluded from aggregation, > 0 is the last exported date <br />
|-<br />
|overridden <br />
|int(10) <br />
|<center>0</center> <br />
|0 is not overridden, > 0 is the last overridden date <br />
|-<br />
|feedback <br />
|text <br />
|<center>NULL</center> <br />
|Manual feedback from the teacher. Could be a code like 'mi'. <br />
|-<br />
|feedbackformat<br />
|int(10)<br />
|<center>0</center> <br />
|Text format for feedback<br />
|-<br />
|information <br />
|text <br />
|<center>NULL</center> <br />
|not sued yet (Further information like forum rating distribution 4/5/7/0/1 ?)<br />
|-<br />
|informationformat<br />
|int(10)<br />
|<center>0</center> <br />
|Text format for information<br />
|-<br />
|timecreated<br />
|int(10) <br />
|<br />
|temporary hack - the date of submission in activity if any, new field expected in 2.0<br />
|-<br />
|timemodified<br />
|int(10) <br />
|<br />
|temporary hack - the date of grading in activity or date of manual grading in gradebook, new field expected in 2.0<br />
|}<br />
<br />
=== grade_outcomes ===<br />
<br />
This table describes the outcomes used in the system. An outcome is a statement tied to a rubric scale from low to high, such as “Not met, Borderline, Met” (stored as 0,1 or 2). For more info about these see [[Development:Outcomes]].<br />
<br />
{| border="1" cellpadding="2" cellspacing="0"<br />
|'''Field''' <br />
|'''Type''' <br />
|'''Default''' <br />
|'''Info''' <br />
<br />
|-<br />
|'''id''' <br />
|int(10) <br />
|<br />
|autoincrementing <br />
<br />
|-<br />
|'''courseid''' <br />
|int(10) <br />
|<center>NULL</center> <br />
|Mostly these are defined site wide ie NULL <br />
<br />
|-<br />
|shortname <br />
|varchar(255) <br />
|<br />
|The short name or code for this outcome statement <br />
<br />
|-<br />
|fullname <br />
|text <br />
|<br />
|The full description of the outcome (usually 1 sentence) <br />
<br />
|-<br />
|'''scaleid''' <br />
|int(10) <br />
|<br />
|The recommended scale for this outcome. <br />
|-<br />
|description <br />
|text <br />
|<center>NULL</center> <br />
|The full description of the outcome (usually 1 sentence) <br />
|-<br />
|timecreated<br />
|int(10) <br />
|<br />
|the time this outcome was first created <br />
<br />
|-<br />
|timemodified<br />
|int(10) <br />
|<br />
|the time this outcome was last updated <br />
<br />
|-<br />
|'''usermodified'''<br />
|int(10) <br />
|<center>NULL</center> <br />
|the userid of the person who last modified this outcome<br />
|}<br />
<br />
=== grade_outcomes_courses ===<br />
An intersection table used to make standard outcomes available to courses.<br />
<br />
{| border="1" cellpadding="2" cellspacing="0"<br />
|'''Field''' <br />
|'''Type''' <br />
|'''Default''' <br />
|'''Info''' <br />
<br />
|-<br />
|'''id''' <br />
|int(10) <br />
|<br />
|autoincrementing <br />
<br />
|-<br />
|'''courseid'''<br />
|int(10)<br />
|<br />
|The id of the course being assigned the outcome<br />
<br />
|-<br />
|'''outcomeid''' <br />
|int(10) <br />
|<br />
|The id of the outcome being assigned to the course<br />
|}<br />
<br />
=== grade_import_newitem ===<br />
<br />
{| border="1" cellpadding="2" cellspacing="0"<br />
|'''Field''' <br />
|'''Type''' <br />
|'''Default''' <br />
|'''Info''' <br />
<br />
|-<br />
|'''id''' <br />
|int(10) <br />
|<br />
|autoincrementing <br />
<br />
|-<br />
|itemname<br />
|varchar(255)<br />
|<br />
|*TODO* Document<br />
<br />
|-<br />
|importcode<br />
|int(12) <br />
|<br />
|*TODO* Document <br />
|}<br />
<br />
=== grade_import_values ===<br />
<br />
{| border="1" cellpadding="2" cellspacing="0"<br />
|'''Field''' <br />
|'''Type''' <br />
|'''Default''' <br />
|'''Info''' <br />
<br />
|-<br />
|'''id''' <br />
|int(10) <br />
|<br />
|autoincrementing <br />
<br />
|-<br />
|'''itemid''' <br />
|int(10) <br />
|NULL<br />
|*TODO* Document <br />
<br />
|-<br />
|newgradeitem<br />
|int(10)<br />
|NULL<br />
|*TODO* Document<br />
<br />
|-<br />
|'''userid''' <br />
|int(10) <br />
|<br />
|*TODO* Document <br />
<br />
|-<br />
|finalgrade<br />
|float(10,5) <br />
|NULL<br />
|*TODO* Document <br />
<br />
|-<br />
|feedback<br />
|text<br />
|NULL<br />
|*TODO* Document <br />
<br />
|-<br />
|importcode<br />
|int(12) <br />
|<br />
|*TODO* Document <br />
|}<br />
<br />
=== History tables ===<br />
<br />
These table keep track of changes to most of the grade tables. Using these it should be possible to reconstruct the grades at any point in time in the past, or to audit grade changes over time. It should be quicker to use these tables for that, rather than storing this information in the main Moodle log. The following tables are set up for that purpose:<br />
<br />
#grade_categories_history<br />
#grade_grades_history<br />
#grade_items_history<br />
#grade_outcomes_history<br />
<br />
Each of them has exactly the same DB structure as their matching table (e.g. grade_categories), with 3 extra fields:<br />
<br />
<br />
<br />
{| border="1" cellpadding="2" cellspacing="0"<br />
|'''Field''' <br />
|'''Type''' <br />
|'''Default''' <br />
|'''Info''' <br />
<br />
|-<br />
|action<br />
|int(10) <br />
|0<br />
|The action that lead to the change being recorded (insert, update, delete)<br />
<br />
|-<br />
|'''oldid''' <br />
|int(10) <br />
|<br />
|The id of the record being changed or inserted (PK of the main table, not the history table) <br />
<br />
|-<br />
|source<br />
|varchar(255)<br />
|NULL<br />
|The module from which the action originated <br />
|}<br />
<br />
=== grade_letters ===<br />
<br />
{| border="1" cellpadding="2" cellspacing="0"<br />
|'''Field''' <br />
|'''Type''' <br />
|'''Default''' <br />
|'''Info''' <br />
<br />
|-<br />
|'''id''' <br />
|int(10) <br />
|<br />
|autoincrementing <br />
<br />
|-<br />
|contextid<br />
|int(10)<br />
|<br />
|What contextid does this letter apply to (from levels CONTEXT_SYSTEM, CONTEXT_COURSECAT or CONTEXT_COURSE)<br />
<br />
|-<br />
|lowerboundary<br />
|float(10,5) <br />
|<br />
|The lower boundary of the letter. Its upper boundary is the lower boundary of the next highest letter, unless there is none above, in which case it's grademax for that grade_item.<br />
<br />
|-<br />
|letter<br />
|varchar(255) <br />
|<br />
|The display value of the letter. Can be any character or string of characters (OK, A, 10% etc..) <br />
|}<br />
<br />
== Overview of module communication ==<br />
<br />
Modules usually store raw grades internally and pass them into gradebook every time they change. Gradebook may also request activities to resend the grades. <br />
<br />
The gradebook is designed to be as separate as possible from the code of activities - modules do not read grade tables or use internal gradebook API. <br />
<br />
Originally it was planned to use new events API, but in the end it was decided to use minimal API consisting of several function in lib/gradelib.php and each mod/xxx/lib.php<br />
<br />
=== Backward compatibility with Moodle 1.8 and earlier ===<br />
<br />
Function grade_grab_legacy_grades($courseid) may be used to request transfer of grades from legacy or 3rd party activities which were not yet converted to new grade API. This function is not called automatically.<br />
<br />
Modules are responsible to push existing grades into gradebook during upgrade.<br />
<br />
==API for communication with modules/blocks==<br />
<br />
Modules may use only functions from lib/gradelib.php which are marked as public. This API may be extended in later 1.9.x release. Activities should access/update only own grades.<br />
<br />
===grade_get_grades()===<br />
<br />
grade_get_grades($courseid, $itemtype, $itemmodule, $iteminstance, $userid_or_ids=0)<br />
<br />
Returns grading information for given activity - optionally with users grades. Manual, course or category items can not be queried.<br />
<br />
===grade_get_outcomes()===<br />
<br />
grade_get_outcomes($courseid, $itemtype, $itemmodule, $iteminstance,$userid=0)<br />
<br />
Returns list of outcomes used in course together with current outcomes for this user.<br />
<br />
===grade_is_locked()===<br />
<br />
grade_is_locked($courseid, $itemtype, $itemmodule, $iteminstance, $itemnumber, $userid=NULL)<br />
<br />
This function will tell a module whether a grade (or grade_item if $userid is not given) is currently locked or not. If it's locked to the current user then the module can print a nice message or prevent editing in the module. If no $userid is given, the method will always return the grade_item's locked state. If a $userid is given, the method will first check the grade_item's locked state (the column). If it is locked, the method will return true no matter the locked state of the specific grade being checked. If unlocked, it will return the locked state of the specific grade.<br />
([http://moodle.org/mod/forum/discuss.php?d=69223#p311329 info])<br />
<br />
===grade_update()===<br />
<br />
grade_update($source, $courseid, $itemtype, $itemmodule, $iteminstance, $itemnumber, $grades=NULL, $itemdetails=NULL)<br />
<br />
Submit new or update grade; update/create grade_item definition. Grade must have userid specified, rawgrade and feedback with format are optional. rawgrade NULL means 'Not graded', missing property or key means do not change existing. Only following grade item properties can be changed 'itemname', 'idnumber', 'gradetype', 'grademax', 'grademin', 'scaleid', 'multfactor', 'plusfactor', 'deleted'.<br />
<br />
===grade_update_outcomes()===<br />
<br />
grade_update_outcomes($source, $courseid, $itemtype, $itemmodule, $iteminstance, $userid, $data)<br />
<br />
Updates outcomes of a given user. Manual outcomes cannot be updated.<br />
<br />
== Private gradebook API ==<br />
Private API is used by gradebook plugins and core Moodle code, it may change in 2.0. Most of the interesting classes and functions are in lib/gradelib.php, grade/lib.php and grade/report/lib.php.<br />
<br />
The following 3 functions are all in /lib/gradelib.php<br />
<br />
===grade_regrade_final_grades()===<br />
<br />
grade_regrade_final_grades($courseid=NULL, $userid=NULL, $updated_item=NULL)<br />
<br />
Updates all grade_grades->finalgrade records for each grade_item matching the given attributes. The search is further restricted, so that only grade_items that have needs_update == true or that use calculation are retrieved and used for the update. The function returns the number of grade_items updated (NOT the same as the number of grades_grades updated!).<br />
<br />
===grade_verify_idnumber()===<br />
<br />
grade_verify_idnumber($idnumber, $grade_item = null, $cm = null, $gradeitem)<br />
<br />
Verify new value of idnumber - checks for uniqueness of new idnubmers, existing are kept intact.<br />
<br />
===remove_course_grades()===<br />
<br />
remove_course_grades($courseid, $showfeedback)<br />
<br />
Remove all grade related course data - history is kept<br />
<br />
<br />
TODO: add description of the other methods and classes + simple usage examples + querylib.php description<br />
<br />
== Dealing with multiple grades ==<br />
<br />
Modules usually produce only one grade item per activity. Optionally one or more outcomes may be attached to activities.<br />
<br />
Some activities may need to aggregate multiple ratings or attempts before sending them into the gradebook. Activities can not send variable number of items.<br />
<br />
If the gradebook receives multiple grade items from a module, then they are automatically grouped together in a unique grade category (with the same name as the module instance). See [[Development:Outcomes]] for more details.<br />
<br />
TODO: this may still be changed<br />
<br />
== Calculated grade items ==<br />
<br />
Categories or manual items maybe calculated using spreadsheet-like formulas. Formulas may reference other items from the same course only using Id numbers in double square brackets.<br />
<br />
eg: <nowiki>= MEAN([[quiz121]], [[quizend]]) + [[assignmentAXC]] + 20.0</nowiki><br />
<br />
== Regrading / updating of final grades ==<br />
<br />
TODO: describe needsupdate flag and incremental updates<br />
<br />
== Adjustment of raw grades ==<br />
Grade_item contains optional rules for adjusting the raw grade before it is cached into a final grade. These rules are processed BEFORE the calculation discussed above. Scale is never changed. Multfactor and plusfactor may be used to alter raw grades coming from activities, but it is recommended to use formulas instead.<br />
<br />
== Displaying the grades to ordinary participants ==<br />
<br />
The module takes responsibility for displaying grades within the module (to a student, say). It is recommended to use the real final grades obtained using grade_get_grades() functionBecause guidebook might force hiding, override grade, etc.<br />
<br />
For full display of grades in a whole course say, the student uses the same link as teachers use to access the gradebook. However, due to their different permissions they will only have access to specific reports. By default this is the ''User report'' report which only shows their own grades and has very few configuration options.<br />
<br />
== Locked grades ==<br />
<br />
Both whole columns and individual grades can be locked in the gradebook, via the ''locked'' field. Teachers may want to do this to prevent further changes from the modules, or from other teachers. When a grade is locked, any changes that might affect that grade are ignored. When the graded is unlocked, activities are asked to resend the latest grades.<br />
<br />
In the main GUIs the lock toggling will be achieved by clicking on a little padlock icon beside each entry or column.<br />
<br />
There is also an option to lock grade or item after some specified date.<br />
<br />
== Overridden grades ==<br />
<br />
Grades can be manually modified (overridden) in the gradebook. When this is done the entered value is always used instead of the aggregated, calculated or activity grade.<br />
<br />
Once grades have been overriden in the gradebook they become read only in the original module. The module should provide a visual indication as to why the grade cannot be modified.<br />
<br />
The need to improve how the module expresses that a grade has been overridden will be reduced by the new [https://docs.moodle.org/en/Development:Grading_interface_2.0 grading interface]<br />
<br />
== Hidden grades and categories ==<br />
<br />
Grades and categories can be hidden in the gradebook or the "categories and items" screen. When a category is hidden all the grade items within it are automatically hidden as well. When a category is un-hidden then all the grade items within it are un-hidden.<br />
<br />
The teacher always sees totals calculated from all relevant items (hidden or un-hidden)<br />
<br />
(Features below were added in 1.9.8 and 2.0)<br />
<br />
When a grade is shown its parent category will also be shown if it was hidden. MDL-21367<br />
<br />
The teacher decides what ordinary users can see in the case of totals that include hidden grades (MDL-21218, in 1.9.8 and 2.0). The user and overview report each have a setting to choose between:<br />
<br />
# Hide any totals that are dependent on a hidden item (show a hyphen there) [DEFAULT]<br />
# Display totals excluding the hidden items<br />
# Display full totals including the hidden items (may allow students to back-calculate hidden grades)<br />
<br />
== Logging ==<br />
<br />
All grading related changes maybe logged in history tables.<br />
<br />
== Security Issues ==<br />
<br />
For security an option to force SSL for the gradebook might be good.<br />
<br />
==Overall grade==<br />
<br />
Each course has exactly one course grade item. It may be used for this purpose now. Other course completion criteria will be implemented in 2.0.<br />
<br />
== Report plugins ==<br />
All the main interface of the gradebook are implemented as report plugins. Each plugin is fully responsible for page layout, there are some handy functions in grade/lib.php. They can even define their own capabilities and extra tables if the core tables are not enough, as they'll have a full /grade/report/xxxx/db directory.<br />
<br />
Each report defines one capability to allow people to see that report, so that admins have control over who can see what reports. For example, the participant interface can be a totally separate report plugin.<br />
<br />
This allows for the widest flexibility and safety in how grades are presented.<br />
<br />
=== Default teacher interface ===<br />
This interface will be what teachers see by default, and will subsume everything the current interface (in Moodle 1.8) does.<br />
<br />
Some snippets of functionality:<br />
{{Moodle 1.9}}<br />
Overall it's a grid, with participant names down one side and grade items along the top. <br />
<br />
Columns will be able to be collapsed together by grouping them into categories. Grades for categories can be calculated via various means. <br />
<br />
“Eye-cons” on the columns and checkboxes by every grade (this bit possibly controlled with a switch) allow hiding by category, by column, by individual grade.<br />
<br />
Textual notes can be added to each grade for more info. These show up to participants as well.<br />
<br />
A groups menu allows the teacher to switch between showing EACH of the groups they have access to, or ALL the groups they have access to.<br />
<br />
All grade items will link to modulepath/grade.php?id=44 which will work out what the current person should be allowed to see and either redirect them to the correct page or just show them immediately. This copes with situations like the quiz, say, where we want editing teachers to go to the detailed reports there while participants just see their own grade or whatever the quiz is set to show.<br />
<br />
User preference to SWITCH between showing raw grades, percentage grades, or both, or grade letters (A/B/C etc). <br />
<br />
Settings for grade letters not only define the transformation from percentage to grades, but also the transformation from letters to grades (in case the teacher edits some of the letter grades).<br />
<br />
Categories are shown above the headings for each column. Clicking for more info on a category will just show the category with a summary column showing total/average for just that category (PLUS the summary column for the whole course).<br />
<br />
All columns should be sortable up/down.<br />
<br />
At the bottom of each column is a row with the mean course score. If in groups mode, then add ANOTHER row with just the group mean. Add the number of grades used in brackets. eg 56% (11). When the report is paged, these means are still for the whole course/group (not the page!)<br />
<br />
{{Moodle 2.0}}<br />
<br />
Teachers can type “straight into” the grid using AJAX or fallback to forms. No popup menus for values.<br />
<br />
Later on we can support customisable shorthand codes to make data entry quick (eg type 'ab' for absent, or 'nge' for not good enough).<br />
<br />
See [http://test.moodle.com/grade/report/grader/index.php?id=2 the test site] for a live demo of this report.<br />
<br />
=== Default participant interface ===<br />
This interface will be what participants see by default:<br />
<br />
Some snippets of functionality:<br />
<br />
*Invert the grid to show one item per row, with the total/average at the bottom.<br />
*Use second/third columns to show categories.<br />
*Include ranking score in another column.<br />
*Show feedback<br />
*Show percentage<br />
*No editing functionality.<br />
<br />
See [http://test.moodle.com/grade/report/user/index.php?id=2 the test site] for a live demo of this report.<br />
<br />
=== Outcomes report ===<br />
This simple informational report displays all the outcomes used by the course, with the following information:<br />
<br />
*Outcome name<br />
*Overall average: If the outcome is used by more than one activity, this shows you the mean across all these activities in the current course<br />
*Site-wide: Yes or No: A site-wide outcome is automatically made available to all courses.<br />
*Activities: A list of links to the activities in the current course that use each outcome. One row per activity (table splits here)<br />
*Average: For each activity using the outcome, the average score is shown.<br />
*Number of grades: For each activity using the outcome, the number of grades is shown (non-graded participants are ignored)<br />
<br />
See [http://test.moodle.com/grade/report/outcomes/index.php?id=2 the test site] for a live demo of this report.<br />
<br />
=== Overview report ===<br />
Another basic report, showing a participant's course averages in each of the courses in which s/he has received grades.<br />
<br />
See [http://test.moodle.com/grade/report/overview/index.php the test site] for a live demo of this report.<br />
<br />
== Export plugins ==<br />
<br />
The API for these is extremely simple. Each export plugin should occupy a directory under /grade/export/xyz and needs to provide only an index.php file as a the primary interface. This file just accepts a 'courseid' parameter.<br />
<br />
== Import plugins ==<br />
<br />
Each import plugin should occupy a directory under /grade/import/xyz and needs to provide only an index.php file as a the primary interface. This file just accepts a 'courseid' parameter.<br />
<br />
The index.php will show an interface for further options and selections.<br />
<br />
Import plugin must validate data before starting the import operation, if some parts of import fail the user must be notified.<br />
<br />
Some sample import plugins are:<br />
<br />
===Import from CSV===<br />
<br />
Accepts an upload of (or URL to) a CSV file. Multiple options describe how to process the file, which columns to add etc. The imported grades always override current grades.<br />
<br />
===Import from XML===<br />
<br />
Accepts an upload of (or URL to) an XML file with this kind of format (from OU). <br />
<br />
<results batch="[someuniqueimportnumber]"><br />
<result><br />
<state>['new' or 'regrade']</state><br />
<assignment>[idnumber]</assignment><br />
<student>[studentid]</student><br />
<score>[score]</score><br />
</result><br />
<result><br />
<state>['new' or 'regrade']</state><br />
<assignment>[idnumber]</assignment><br />
<student>[studentid]</student><br />
<score>[score]</score><br />
</result><br />
[...]<br />
</results><br />
<br />
== Capabilities and Permissions ==<br />
<br />
* moodle/grade:view - view own grades or grades of other user if used in CONTEXT_USER<br />
<br />
* moodle/grade:viewall - view grades of all users<br />
<br />
* moodle/grade:viewhidden - see grades that are marked as hidden for the owner<br />
<br />
* moodle/grade:hide - be able to hide/unhide cells, items or categories<br />
<br />
* moodle/grade:lock - be able to lock cells, items or categories<br />
<br />
* moodle/grade:unlock - be able to unlock cells, items or categories<br />
<br />
* moodle/grade:manage - manage grade items and categories in gradebook (create, edit, lock, hide, delete, etc.)<br />
<br />
* moodle/grade:import - general import grades, requires separate permission for each plugin<br />
<br />
* moodle/grade:export - export grades, requires separate permission for each plugin<br />
<br />
* gradereport/grader:view - can view the grader report<br />
<br />
* gradeimport/csv:view - can view/use the csv import plugin<br />
<br />
* gradeexport/csv:view - can view/use the csv export plugin<br />
<br />
* moodle:site/accessallgroups<br />
<br />
== Development Tasks and Tracking ==<br />
<br />
For details of 1.9 development see [http://tracker.moodle.org/browse/MDL-9137 MDL-9137]<br />
<br />
For details of 2.0 development see [https://docs.moodle.org/en/Development:Gradebook_improvements Gradebook_imporovements] and [http://tracker.moodle.org/browse/MDL-19131 MDL-19131]<br />
<br />
==Updating module code==<br />
Module authors must implement new gradebook API and add upgrade code for migration of old grades into new gradebook. Fortunately the needed changes are not big.<br />
<br />
Steps:<br />
*add xxx_update_grades() function into mod/xxx/lib.php<br />
*add xxx_grade_item_update() function into mod/xxx/lib.php<br />
*patch xxx_update_instance(), xxx_add_instance() and xxx_delete_instance() to call xxx_grade_item_update()<br />
*patch all places of code that change grade values to call xxx_update_grades()<br />
*patch code that displays grades to students to use final grades from the gradebook<br />
<br />
There are many examples in official modules, assignment has the most advanced implementation.<br />
<br />
== Ideas for the future ==<br />
{{Moodle 2.0}}<br />
TODO: add new meta issue into tracker<br />
<br />
*option to aggregate including/excluding hidden grades - needs db changes<br />
*option to rollback all changes during import operation if anything fails<br />
*performance improvements<br />
*conditional activities<br />
*course completion criteria<br />
*better public API for modules<br />
*better API for gradebook plugins<br />
*better state tracking in export plugins<br />
*ajax reports<br />
*specialised reports<br />
*submission and marking date tracking db changes<br />
*calculation formula improvements<br />
*historical views<br />
*individual graph of grades (time vs %). Bar graph, lineal graph. Add (or not) the maximum posible; line of 0 (=minimum), 25, 50 (=median), 75 and 100 (=max) percentils of the group.<br />
*<br />
<br />
== See also ==<br />
<br />
* [http://moodle.org/mod/forum/discuss.php?d=69223&mode=3 Gradebook Development ideas] forum discussion<br />
* Using Moodle [http://moodle.org/mod/forum/discuss.php?d=51107 New gradebook for Moodle] forum discussion<br />
* [[Development:Gradebook Report Tutorial]]<br />
<br />
[[Category:Developer|Grades]]<br />
[[Category:Grades]]</div>Andyjdavishttps://docs.moodle.org/20/en/index.php?title=Development:Grades&diff=79035Development:Grades2010-12-10T03:45:16Z<p>Andyjdavis: /* Executive Summary */</p>
<hr />
<div>{{Work in progress}}<br />
<br />
== Executive Summary ==<br />
<br />
This document primarily describes the current workings of the gradebook. For more detailed information about current gradebook development see [[Development:Gradebook_improvements]]<br />
<br />
The gradebook mechanisms must be rebuilt to:<br />
<br />
# '''Improve performance and scalability''' - All grades from throughout the system will be pushed to a central system of tables. This means reports based on grades can be generated much faster, and the gradebook has ultimate control over the content.<br />
# '''Improve flexibility''' - All aspects of the new gradebook will use simple plugin structures, namely: exports, imports and displays/reports. It is expected that the community will be very active in producing [[Development:Gradebook Report Tutorial |special-purpose reports]] analysing the basic grade data in new ways, for example, or writing plugins to transfer grades to student information systems.<br />
# '''Allow rubrics for outcomes (aka standards,competencies,goals)''' - As well as numerical grades, each grading item can consist of a number of scores made on a rubric against a standard outcome statement. These can be automatically converted to a numerical grade if desired or just shown as is.<br />
# '''Allow arbitrary columns and derived columns''' - Arbitrary columns of data can be added (either manually or via import). Columns can also be automatically filled based on formulas.<br />
# '''Implement limited public API''' - Activities may use this API to send grades/outcomes to gradebook and find out the final grades.<br />
<br />
== Glossary ==<br />
<br />
Here are some terms used in the gradebook, both in the development and the user interface. Using these terms in discussions about the gradebook will help to reduce confusion.<br />
<br />
{| class="nicetable"<br />
!Term<br />
!Definition<br />
|-<br />
|Activity<br />
|An instance of an activity module [[Category:Modules|Module]] (e.g. a single quiz, assignment etc...)<br />
|-<br />
|Calculation<br />
|A formula used to calculate grades, based (optionally) on other grade items. Not the same as [[Calculated_question_type|Calculated question types]].<br />
|-<br />
|Category<br />
|A set of Grade Items. A Category also has its own aggregated Grade which is calculated from its Grade Items. There is no limit to the level of nesting of Categories (a Category may belong to another Category). However, each Grade Item may belong to only one Category. <br />
|-<br />
|Course completion<br />
|The concept of meeting certain criteria for completing a course. In the context of the gradebook, this means a set of grades that must be reached, or a number of outcomes/competencies to complete/master.<br />
|-<br />
|Grade<br />
|A Grade is a single assessment. It may be a number or an item on a scale (possibly tied to an Outcome). Raw grade value is the numerical or scale grade from activity. Final grade is the grade reported in gradebook.<br />
|-<br />
|[[Gradebook|Gradebook]]<br />
|A central location in Moodle where students' Grades are stored and displayed. Teachers can keep track of their students' progress and organise which set of Grades their students will be able to see. Students see their own Grades.<br />
|-<br />
|Grade Item<br />
|A "column" of Grades. It can be created from a specific Activity or other module, calculated from other Grade Items, or entered manually.<br />
|-<br />
|[[Development:Grades#Locked_grades|Grade Locks]]<br />
|See linked section of this page<br />
|-<br />
|History<br />
|The gradebook has its own type of log, which keeps a History of all changes made to grades.<br />
|-<br />
|[[Development:Outcomes|Outcome]]<br />
|[[Development:Outcomes|Outcomes]] are specific descriptions of what a person is expected to be able to do or understand at the completion of an activity or course. An activity might have more than one outcome, and each may have a grade against it (usually on a scale). Other terms for Outcomes are ''Competencies'' and ''Goals''. See some [[Development:Outcomes_examples|Examples]].<br />
|-<br />
|[[Scales|Scale]]<br />
|A scale is a set of responses from which the teacher can choose one. eg Very cool, Cool, Fairly cool, Not very cool, Not cool<br />
|-<br />
|Letter Grades<br />
|Special representation of grade values similar to scales. Letters are configured in course contexts or above and are defined by lower boundary. eg A (above 90 %), B (above 80 %), C (above 70 %), D (above 50 %), F (above 0 %)<br />
<br />
|}<br />
<br />
== Database structures ==<br />
=== grade_items ===<br />
<br />
This table keeps information about gradeable items (ie columns). If an activity (eg an assignment or quiz) has multiple grade_items associated with it (eg several outcomes and numerical grade), then there will be a corresponding multiple number of rows in this table.<br />
<br />
idnumber is a tag unique inside a course identifying the grade item, useful for identifying data in exports and for referring to the grade item in calculations. It is the same as the idnumber in course_modules.<br />
<br />
<br />
{| border="1" cellpadding="2" cellspacing="0"<br />
|'''Field''' <br />
|'''Type''' <br />
|'''Default''' <br />
|'''Info''' <br />
|-<br />
|'''id''' <br />
|int(10) <br />
|<br />
|autoincrementing <br />
|-<br />
|'''courseid''' <br />
|int(10) <br />
|<br />
|The course this item is part of <br />
|-<br />
|'''categoryid''' <br />
|int(10) <br />
|<center>NULL</center> <br />
|the category group this item belongs to <br />
|-<br />
|itemname <br />
|varchar(255) <br />
|<center>NULL</center> <br />
|The name of this item (pushed in by the module or entered by user) <br />
|-<br />
|'''itemtype''' <br />
|varchar(30) <br />
|<br />
|'mod', 'blocks', 'manual', 'course', 'category' etc <br />
|-<br />
|itemmodule <br />
|varchar(30) <br />
|<center>NULL</center> <br />
|'forum', 'quiz', 'csv', etc <br />
|-<br />
|iteminstance <br />
|int(10) <br />
|<center>NULL</center> <br />
|id of the item module <br />
|-<br />
|itemnumber <br />
|int(10) <br />
|<center>NULL</center> <br />
|Can be used to distinguish multiple grades for an activity <br />
|-<br />
|iteminfo <br />
|text <br />
|<center>NULL</center> <br />
|Info and notes about this item XXX <br />
|-<br />
|'''idnumber'''<br />
|varchar(255) <br />
|<center>NULL</center> <br />
|Arbitrary idnumber provided by the module responsible (optional and course unique)<br />
|-<br />
|calculation <br />
|text<br />
|<center>NULL</center> <br />
|Spreadsheet-type formula used to process the raw grades into final grades<br />
|-<br />
|'''gradetype''' <br />
|int(4) <br />
|<center>1</center> <br />
|0 = none, 1 = value, 2 = scale, 3 = text <br />
|-<br />
|grademax <br />
|float(10,5) <br />
|<center>100</center> <br />
|What is the maximum allowable grade? <br />
|-<br />
|grademin <br />
|float(10,5) <br />
|<center>0</center> <br />
|What is the minimum allowable grade? <br />
|-<br />
|'''scaleid''' <br />
|int(10) <br />
|<center>NULL</center> <br />
|If this grade is based on a scale, which one is it? <br />
|-<br />
|'''outcomeid''' <br />
|int(10) <br />
|<center>NULL</center> <br />
|If this is outcome item, which outcome is it? <br />
|-<br />
|gradepass<br />
|float(10,5) <br />
|<center>0</center> <br />
|What grade is needed to pass? grademin <= gradepass <= grademax<br />
|-<br />
|multfactor <br />
|float(10,5) <br />
|<center>1.0</center> <br />
|Multiply all raw grades from activities by this <br />
|-<br />
|plusfactor <br />
|float(10,5) <br />
|<center>0.0</center> <br />
|Add this to all raw grades from activities by this <br />
|-<br />
|aggregationcoef <br />
|float(10,5) <br />
|<center>0.0</center> <br />
|Weight applied to all grades in this grade item during aggregation with other grade items.<br />
|-<br />
|sortorder <br />
|int(10) <br />
|<center>0</center> <br />
|Sorting order of the columns (pre-order walk of the grading tree)<br />
|-<br />
|display<br />
|int(10) <br />
|<center>0</center> <br />
|Display as real grades, percentages (in reference to the minimum and maximum grades) or letters (A, B, C etc..), or course default (0)<br />
|-<br />
|hidden <br />
|int(10) <br />
|<center>0</center> <br />
|1 is hidden, 1 is hide always, > 1 is a date to hide until (prevents viewing of all user grades) <br />
|-<br />
|'''locked'''<br />
|int(10) <br />
|<center>0</center> <br />
|0 is not locked, > 0 is a date when was item locked (no final grade or grade_item updates possible)<br />
|-<br />
|'''locktime'''<br />
|int(10) <br />
|<center>0</center> <br />
|0 no auto locking, > 0 is a date to lock grade item and final grades after automatically <br />
|-<br />
|deleted <br />
|int(10) <br />
|<center>0</center> <br />
|1 means the associated module instance has been deleted<br />
|-<br />
|'''needsupdate'''<br />
|int(10) <br />
|<center>0</center> <br />
|If this flag is set, then the whole column will be recalculated. If set in course item, some other item needs recalculation. Calculated and category items are recalculated together with any other items.<br />
|-<br />
|timecreated <br />
|int(10)<br />
|<br />
|The first time this grade_item was created<br />
|-<br />
|timemodified <br />
|int(10)<br />
|<br />
|The last time this grade_item was modified<br />
|}<br />
<br />
=== grade_categories ===<br />
<br />
This table keeps information about categories, used for grouping items. An associated grade_item will be maintained for each category to store the aggregate data.<br />
<br />
{| border="1" cellpadding="2" cellspacing="0"<br />
|'''Field''' <br />
|'''Type''' <br />
|'''Default''' <br />
|'''Info''' <br />
|-<br />
|'''id''' <br />
|int(10) <br />
|<br />
|autoincrementing <br />
|-<br />
|'''courseid''' <br />
|int(10) <br />
|<br />
|The course this grade category is part of <br />
|-<br />
|'''parent''' <br />
|int(10) <br />
|<center>NULL</center> <br />
|Parent grade_category (hierarchical)<br />
|-<br />
|depth<br />
|int(10) <br />
|<center>0</center> <br />
|How deep is this category from the highest level (1,2,3)<br />
|-<br />
|path<br />
|varchar(255) <br />
| <br />
|Shows the path as /1/2/3/ <br />
|-<br />
|fullname <br />
|varchar(255) <br />
|<br />
|The name of this grade category <br />
|-<br />
|aggregation <br />
|int(10) <br />
|<center>0</center> <br />
|A constant pointing to one of the predefined aggregation strategies (none, mean,median,sum, etc) <br />
|-<br />
|keephigh <br />
|int(10) <br />
|<center>0</center> <br />
|Keep only the X highest items <br />
|-<br />
|droplow <br />
|int(10) <br />
|<center>0</center> <br />
|Drop the X lowest items <br />
|-<br />
|aggregateonlygraded<br />
|int(1) <br />
|<center>0</center> <br />
|Aggregate only existing grades <br />
|-<br />
|aggregateoutcomes<br />
|int(1) <br />
|<center>0</center> <br />
|Aggregate otcomes together with normal items <br />
|-<br />
|aggregatesubcats<br />
|int(1) <br />
|<center>0</center> <br />
|Aggregate only items placed directly in category or all items in subcategories excluding the subcategory totals <br />
|-<br />
|timecreated<br />
|int(10) <br />
|<br />
|The first time this grade_category was created<br />
|-<br />
|timemodified <br />
|int(10) <br />
|<br />
|The last time this grade_category was modified<br />
|}<br />
<br />
=== grade_grades ===<br />
<br />
This table keeps individual grades for each user and each item. The raw grade is exactly as imported or submitted by modules. The rawgrademax/min and rawscaleid are stored here to record the values at the time the grade was stored, because teachers might change this for an activity! All the results are normalised/resampled/calculated for the finalgrade, which is relative to the max/min/scaleid values stored in the grade_item. The finalgrade field is effectively a cache and values are rebuilt whenever raw values or the grade_item changes.<br />
<br />
Note that the finalgrade for a scale-based item may be non-integer! It needs to be rounded on display.<br />
<br />
{| border="1" cellpadding="2" cellspacing="0"<br />
|'''Field''' <br />
|'''Type''' <br />
|'''Default''' <br />
|'''Info''' <br />
|-<br />
|'''id''' <br />
|int(10) <br />
|<br />
|autoincrementing <br />
|-<br />
|'''itemid''' <br />
|int(10) <br />
|<br />
|The item this grade belongs to <br />
|-<br />
|'''userid''' <br />
|int(10) <br />
|<br />
|The user who this grade is for <br />
|-<br />
|rawgrade<br />
|float(11,10) <br />
|<center>NULL</center> <br />
|The raw grade that came into the system<br />
|-<br />
|rawgrademax <br />
|float(11,10) <br />
|<center>100</center> <br />
|The maximum allowable grade when this was created <br />
|-<br />
|rawgrademin <br />
|float(11,10) <br />
|<center>0</center> <br />
|The minimum allowable grade when this was created <br />
|-<br />
|'''rawscaleid''' <br />
|int(10) <br />
|<center>NULL</center> <br />
|If this grade is based on a scale, which one was it? <br />
|-<br />
|'''usermodified'''<br />
|int(10) <br />
|<center>NULL</center> <br />
|the userid of the person who last modified the raw grade value<br />
|-<br />
|finalgrade<br />
|float(11,10) <br />
|<center>NULL</center> <br />
|The final grade (cached) after all calculations are made. Overriden grades are also stored here.<br />
|- <br />
|hidden <br />
|int(10) <br />
|<center>0</center> <br />
|0 is not hidden, 1 is hide always, > 1 is a date to hide until <br />
|-<br />
|'''locked'''<br />
|int(10) <br />
|<center>0</center> <br />
|0 is not locked, > 0 when was the grade locked<br />
|-<br />
|'''locktime'''<br />
|int(10) <br />
|<center>0</center> <br />
|0 is never, > 0 is a date to lock the final grade after automatically<br />
|-<br />
|exported <br />
|int(10) <br />
|<center>0</center> <br />
|0 is not exported, > 0 is the last exported date <br />
|-<br />
|excluded <br />
|int(10) <br />
|<center>0</center> <br />
|grade excluded from aggregation, > 0 is the last exported date <br />
|-<br />
|overridden <br />
|int(10) <br />
|<center>0</center> <br />
|0 is not overridden, > 0 is the last overridden date <br />
|-<br />
|feedback <br />
|text <br />
|<center>NULL</center> <br />
|Manual feedback from the teacher. Could be a code like 'mi'. <br />
|-<br />
|feedbackformat<br />
|int(10)<br />
|<center>0</center> <br />
|Text format for feedback<br />
|-<br />
|information <br />
|text <br />
|<center>NULL</center> <br />
|not sued yet (Further information like forum rating distribution 4/5/7/0/1 ?)<br />
|-<br />
|informationformat<br />
|int(10)<br />
|<center>0</center> <br />
|Text format for information<br />
|-<br />
|timecreated<br />
|int(10) <br />
|<br />
|temporary hack - the date of submission in activity if any, new field expected in 2.0<br />
|-<br />
|timemodified<br />
|int(10) <br />
|<br />
|temporary hack - the date of grading in activity or date of manual grading in gradebook, new field expected in 2.0<br />
|}<br />
<br />
=== grade_outcomes ===<br />
<br />
This table describes the outcomes used in the system. An outcome is a statement tied to a rubric scale from low to high, such as “Not met, Borderline, Met” (stored as 0,1 or 2). For more info about these see [[Development:Outcomes]].<br />
<br />
{| border="1" cellpadding="2" cellspacing="0"<br />
|'''Field''' <br />
|'''Type''' <br />
|'''Default''' <br />
|'''Info''' <br />
<br />
|-<br />
|'''id''' <br />
|int(10) <br />
|<br />
|autoincrementing <br />
<br />
|-<br />
|'''courseid''' <br />
|int(10) <br />
|<center>NULL</center> <br />
|Mostly these are defined site wide ie NULL <br />
<br />
|-<br />
|shortname <br />
|varchar(255) <br />
|<br />
|The short name or code for this outcome statement <br />
<br />
|-<br />
|fullname <br />
|text <br />
|<br />
|The full description of the outcome (usually 1 sentence) <br />
<br />
|-<br />
|'''scaleid''' <br />
|int(10) <br />
|<br />
|The recommended scale for this outcome. <br />
|-<br />
|description <br />
|text <br />
|<center>NULL</center> <br />
|The full description of the outcome (usually 1 sentence) <br />
|-<br />
|timecreated<br />
|int(10) <br />
|<br />
|the time this outcome was first created <br />
<br />
|-<br />
|timemodified<br />
|int(10) <br />
|<br />
|the time this outcome was last updated <br />
<br />
|-<br />
|'''usermodified'''<br />
|int(10) <br />
|<center>NULL</center> <br />
|the userid of the person who last modified this outcome<br />
|}<br />
<br />
=== grade_outcomes_courses ===<br />
An intersection table used to make standard outcomes available to courses.<br />
<br />
{| border="1" cellpadding="2" cellspacing="0"<br />
|'''Field''' <br />
|'''Type''' <br />
|'''Default''' <br />
|'''Info''' <br />
<br />
|-<br />
|'''id''' <br />
|int(10) <br />
|<br />
|autoincrementing <br />
<br />
|-<br />
|'''courseid'''<br />
|int(10)<br />
|<br />
|The id of the course being assigned the outcome<br />
<br />
|-<br />
|'''outcomeid''' <br />
|int(10) <br />
|<br />
|The id of the outcome being assigned to the course<br />
|}<br />
<br />
=== grade_import_newitem ===<br />
<br />
{| border="1" cellpadding="2" cellspacing="0"<br />
|'''Field''' <br />
|'''Type''' <br />
|'''Default''' <br />
|'''Info''' <br />
<br />
|-<br />
|'''id''' <br />
|int(10) <br />
|<br />
|autoincrementing <br />
<br />
|-<br />
|itemname<br />
|varchar(255)<br />
|<br />
|*TODO* Document<br />
<br />
|-<br />
|importcode<br />
|int(12) <br />
|<br />
|*TODO* Document <br />
|}<br />
<br />
=== grade_import_values ===<br />
<br />
{| border="1" cellpadding="2" cellspacing="0"<br />
|'''Field''' <br />
|'''Type''' <br />
|'''Default''' <br />
|'''Info''' <br />
<br />
|-<br />
|'''id''' <br />
|int(10) <br />
|<br />
|autoincrementing <br />
<br />
|-<br />
|'''itemid''' <br />
|int(10) <br />
|NULL<br />
|*TODO* Document <br />
<br />
|-<br />
|newgradeitem<br />
|int(10)<br />
|NULL<br />
|*TODO* Document<br />
<br />
|-<br />
|'''userid''' <br />
|int(10) <br />
|<br />
|*TODO* Document <br />
<br />
|-<br />
|finalgrade<br />
|float(10,5) <br />
|NULL<br />
|*TODO* Document <br />
<br />
|-<br />
|feedback<br />
|text<br />
|NULL<br />
|*TODO* Document <br />
<br />
|-<br />
|importcode<br />
|int(12) <br />
|<br />
|*TODO* Document <br />
|}<br />
<br />
=== History tables ===<br />
<br />
These table keep track of changes to most of the grade tables. Using these it should be possible to reconstruct the grades at any point in time in the past, or to audit grade changes over time. It should be quicker to use these tables for that, rather than storing this information in the main Moodle log. The following tables are set up for that purpose:<br />
<br />
#grade_categories_history<br />
#grade_grades_history<br />
#grade_items_history<br />
#grade_outcomes_history<br />
<br />
Each of them has exactly the same DB structure as their matching table (e.g. grade_categories), with 3 extra fields:<br />
<br />
<br />
<br />
{| border="1" cellpadding="2" cellspacing="0"<br />
|'''Field''' <br />
|'''Type''' <br />
|'''Default''' <br />
|'''Info''' <br />
<br />
|-<br />
|action<br />
|int(10) <br />
|0<br />
|The action that lead to the change being recorded (insert, update, delete)<br />
<br />
|-<br />
|'''oldid''' <br />
|int(10) <br />
|<br />
|The id of the record being changed or inserted (PK of the main table, not the history table) <br />
<br />
|-<br />
|source<br />
|varchar(255)<br />
|NULL<br />
|The module from which the action originated <br />
|}<br />
<br />
=== grade_letters ===<br />
<br />
{| border="1" cellpadding="2" cellspacing="0"<br />
|'''Field''' <br />
|'''Type''' <br />
|'''Default''' <br />
|'''Info''' <br />
<br />
|-<br />
|'''id''' <br />
|int(10) <br />
|<br />
|autoincrementing <br />
<br />
|-<br />
|contextid<br />
|int(10)<br />
|<br />
|What contextid does this letter apply to (from levels CONTEXT_SYSTEM, CONTEXT_COURSECAT or CONTEXT_COURSE)<br />
<br />
|-<br />
|lowerboundary<br />
|float(10,5) <br />
|<br />
|The lower boundary of the letter. Its upper boundary is the lower boundary of the next highest letter, unless there is none above, in which case it's grademax for that grade_item.<br />
<br />
|-<br />
|letter<br />
|varchar(255) <br />
|<br />
|The display value of the letter. Can be any character or string of characters (OK, A, 10% etc..) <br />
|}<br />
<br />
== Overview of module communication ==<br />
<br />
Modules usually store raw grades internally and pass them into gradebook every time they change. Gradebook may also request activities to resend the grades. <br />
<br />
The gradebook is designed to be as separate as possible from the code of activities - modules do not read grade tables or use internal gradebook API. <br />
<br />
Originally it was planned to use new events API, but in the end it was decided to use minimal API consisting of several function in lib/gradelib.php and each mod/xxx/lib.php<br />
<br />
=== Backward compatibility with Moodle 1.8 and earlier ===<br />
<br />
Function grade_grab_legacy_grades($courseid) may be used to request transfer of grades from legacy or 3rd party activities which were not yet converted to new grade API. This function is not called automatically.<br />
<br />
Modules are responsible to push existing grades into gradebook during upgrade.<br />
<br />
==API for communication with modules/blocks==<br />
<br />
Modules may use only functions from lib/gradelib.php which are marked as public. This API may be extended in later 1.9.x release. Activities should access/update only own grades.<br />
<br />
===grade_get_grades()===<br />
<br />
grade_get_grades($courseid, $itemtype, $itemmodule, $iteminstance, $userid_or_ids=0)<br />
<br />
Returns grading information for given activity - optionally with users grades. Manual, course or category items can not be queried.<br />
<br />
===grade_get_outcomes()===<br />
<br />
grade_get_outcomes($courseid, $itemtype, $itemmodule, $iteminstance,$userid=0)<br />
<br />
Returns list of outcomes used in course together with current outcomes for this user.<br />
<br />
===grade_is_locked()===<br />
<br />
eg grade_is_locked($courseid, $itemtype, $itemmodule, $iteminstance, $itemnumber, $userid=NULL)<br />
<br />
This function will tell a module whether a grade (or grade_item if $userid is not given) is currently locked or not. If it's locked to the current user then the module can print a nice message or prevent editing in the module. If no $userid is given, the method will always return the grade_item's locked state. If a $userid is given, the method will first check the grade_item's locked state (the column). If it is locked, the method will return true no matter the locked state of the specific grade being checked. If unlocked, it will return the locked state of the specific grade.<br />
([http://moodle.org/mod/forum/discuss.php?d=69223#p311329 info])<br />
<br />
===grade_update()===<br />
<br />
grade_update($source, $courseid, $itemtype, $itemmodule, $iteminstance, $itemnumber, $grades=NULL, $itemdetails=NULL)<br />
<br />
Submit new or update grade; update/create grade_item definition. Grade must have userid specified, rawgrade and feedback with format are optional. rawgrade NULL means 'Not graded', missing property or key means do not change existing. Only following grade item properties can be changed 'itemname', 'idnumber', 'gradetype', 'grademax', 'grademin', 'scaleid', 'multfactor', 'plusfactor', 'deleted'.<br />
<br />
===grade_update_outcomes()===<br />
<br />
grade_update_outcomes($source, $courseid, $itemtype, $itemmodule, $iteminstance, $userid, $data)<br />
<br />
Updates outcomes of a given user. Manual outcomes cannot be updated.<br />
<br />
== Private gradebook API ==<br />
Private API is used by gradebook plugins and core Moodle code, it may change in 2.0. Most of the interesting classes and functions are in lib/gradelib.php, grade/lib.php and grade/report/lib.php.<br />
<br />
The following 3 functions are all in /lib/gradelib.php<br />
<br />
===grade_regrade_final_grades()===<br />
<br />
grade_regrade_final_grades($courseid=NULL, $userid=NULL, $updated_item=NULL)<br />
<br />
Updates all grade_grades->finalgrade records for each grade_item matching the given attributes. The search is further restricted, so that only grade_items that have needs_update == true or that use calculation are retrieved and used for the update. The function returns the number of grade_items updated (NOT the same as the number of grades_grades updated!).<br />
<br />
===grade_verify_idnumber()===<br />
<br />
grade_verify_idnumber($idnumber, $grade_item = null, $cm = null, $gradeitem)<br />
<br />
Verify new value of idnumber - checks for uniqueness of new idnubmers, existing are kept intact.<br />
<br />
===remove_course_grades()===<br />
<br />
remove_course_grades($courseid, $showfeedback)<br />
<br />
Remove all grade related course data - history is kept<br />
<br />
<br />
TODO: add description of the other methods and classes + simple usage examples + querylib.php description<br />
<br />
== Dealing with multiple grades ==<br />
<br />
Modules usually produce only one grade item per activity. Optionally one or more outcomes may be attached to activities.<br />
<br />
Some activities may need to aggregate multiple ratings or attempts before sending them into the gradebook. Activities can not send variable number of items.<br />
<br />
If the gradebook receives multiple grade items from a module, then they are automatically grouped together in a unique grade category (with the same name as the module instance). See [[Development:Outcomes]] for more details.<br />
<br />
TODO: this may still be changed<br />
<br />
== Calculated grade items ==<br />
<br />
Categories or manual items maybe calculated using spreadsheet-like formulas. Formulas may reference other items from the same course only using Id numbers in double square brackets.<br />
<br />
eg: <nowiki>= MEAN([[quiz121]], [[quizend]]) + [[assignmentAXC]] + 20.0</nowiki><br />
<br />
== Regrading / updating of final grades ==<br />
<br />
TODO: describe needsupdate flag and incremental updates<br />
<br />
== Adjustment of raw grades ==<br />
Grade_item contains optional rules for adjusting the raw grade before it is cached into a final grade. These rules are processed BEFORE the calculation discussed above. Scale is never changed. Multfactor and plusfactor may be used to alter raw grades coming from activities, but it is recommended to use formulas instead.<br />
<br />
== Displaying the grades to ordinary participants ==<br />
<br />
The module takes responsibility for displaying grades within the module (to a student, say). It is recommended to use the real final grades obtained using grade_get_grades() functionBecause guidebook might force hiding, override grade, etc.<br />
<br />
For full display of grades in a whole course say, the student uses the same link as teachers use to access the gradebook. However, due to their different permissions they will only have access to specific reports. By default this is the ''User report'' report which only shows their own grades and has very few configuration options.<br />
<br />
== Locked grades ==<br />
<br />
Both whole columns and individual grades can be locked in the gradebook, via the ''locked'' field. Teachers may want to do this to prevent further changes from the modules, or from other teachers. When a grade is locked, any changes that might affect that grade are ignored. When the graded is unlocked, activities are asked to resend the latest grades.<br />
<br />
In the main GUIs the lock toggling will be achieved by clicking on a little padlock icon beside each entry or column.<br />
<br />
There is also an option to lock grade or item after some specified date.<br />
<br />
== Overridden grades ==<br />
<br />
Grades can be manually modified (overridden) in the gradebook. When this is done the entered value is always used instead of the aggregated, calculated or activity grade.<br />
<br />
Once grades have been overriden in the gradebook they become read only in the original module. The module should provide a visual indication as to why the grade cannot be modified.<br />
<br />
The need to improve how the module expresses that a grade has been overridden will be reduced by the new [https://docs.moodle.org/en/Development:Grading_interface_2.0 grading interface]<br />
<br />
== Hidden grades and categories ==<br />
<br />
Grades and categories can be hidden in the gradebook or the "categories and items" screen. When a category is hidden all the grade items within it are automatically hidden as well. When a category is un-hidden then all the grade items within it are un-hidden.<br />
<br />
The teacher always sees totals calculated from all relevant items (hidden or un-hidden)<br />
<br />
(Features below were added in 1.9.8 and 2.0)<br />
<br />
When a grade is shown its parent category will also be shown if it was hidden. MDL-21367<br />
<br />
The teacher decides what ordinary users can see in the case of totals that include hidden grades (MDL-21218, in 1.9.8 and 2.0). The user and overview report each have a setting to choose between:<br />
<br />
# Hide any totals that are dependent on a hidden item (show a hyphen there) [DEFAULT]<br />
# Display totals excluding the hidden items<br />
# Display full totals including the hidden items (may allow students to back-calculate hidden grades)<br />
<br />
== Logging ==<br />
<br />
All grading related changes maybe logged in history tables.<br />
<br />
== Security Issues ==<br />
<br />
For security an option to force SSL for the gradebook might be good.<br />
<br />
==Overall grade==<br />
<br />
Each course has exactly one course grade item. It may be used for this purpose now. Other course completion criteria will be implemented in 2.0.<br />
<br />
== Report plugins ==<br />
All the main interface of the gradebook are implemented as report plugins. Each plugin is fully responsible for page layout, there are some handy functions in grade/lib.php. They can even define their own capabilities and extra tables if the core tables are not enough, as they'll have a full /grade/report/xxxx/db directory.<br />
<br />
Each report defines one capability to allow people to see that report, so that admins have control over who can see what reports. For example, the participant interface can be a totally separate report plugin.<br />
<br />
This allows for the widest flexibility and safety in how grades are presented.<br />
<br />
=== Default teacher interface ===<br />
This interface will be what teachers see by default, and will subsume everything the current interface (in Moodle 1.8) does.<br />
<br />
Some snippets of functionality:<br />
{{Moodle 1.9}}<br />
Overall it's a grid, with participant names down one side and grade items along the top. <br />
<br />
Columns will be able to be collapsed together by grouping them into categories. Grades for categories can be calculated via various means. <br />
<br />
“Eye-cons” on the columns and checkboxes by every grade (this bit possibly controlled with a switch) allow hiding by category, by column, by individual grade.<br />
<br />
Textual notes can be added to each grade for more info. These show up to participants as well.<br />
<br />
A groups menu allows the teacher to switch between showing EACH of the groups they have access to, or ALL the groups they have access to.<br />
<br />
All grade items will link to modulepath/grade.php?id=44 which will work out what the current person should be allowed to see and either redirect them to the correct page or just show them immediately. This copes with situations like the quiz, say, where we want editing teachers to go to the detailed reports there while participants just see their own grade or whatever the quiz is set to show.<br />
<br />
User preference to SWITCH between showing raw grades, percentage grades, or both, or grade letters (A/B/C etc). <br />
<br />
Settings for grade letters not only define the transformation from percentage to grades, but also the transformation from letters to grades (in case the teacher edits some of the letter grades).<br />
<br />
Categories are shown above the headings for each column. Clicking for more info on a category will just show the category with a summary column showing total/average for just that category (PLUS the summary column for the whole course).<br />
<br />
All columns should be sortable up/down.<br />
<br />
At the bottom of each column is a row with the mean course score. If in groups mode, then add ANOTHER row with just the group mean. Add the number of grades used in brackets. eg 56% (11). When the report is paged, these means are still for the whole course/group (not the page!)<br />
<br />
{{Moodle 2.0}}<br />
<br />
Teachers can type “straight into” the grid using AJAX or fallback to forms. No popup menus for values.<br />
<br />
Later on we can support customisable shorthand codes to make data entry quick (eg type 'ab' for absent, or 'nge' for not good enough).<br />
<br />
See [http://test.moodle.com/grade/report/grader/index.php?id=2 the test site] for a live demo of this report.<br />
<br />
=== Default participant interface ===<br />
This interface will be what participants see by default:<br />
<br />
Some snippets of functionality:<br />
<br />
*Invert the grid to show one item per row, with the total/average at the bottom.<br />
*Use second/third columns to show categories.<br />
*Include ranking score in another column.<br />
*Show feedback<br />
*Show percentage<br />
*No editing functionality.<br />
<br />
See [http://test.moodle.com/grade/report/user/index.php?id=2 the test site] for a live demo of this report.<br />
<br />
=== Outcomes report ===<br />
This simple informational report displays all the outcomes used by the course, with the following information:<br />
<br />
*Outcome name<br />
*Overall average: If the outcome is used by more than one activity, this shows you the mean across all these activities in the current course<br />
*Site-wide: Yes or No: A site-wide outcome is automatically made available to all courses.<br />
*Activities: A list of links to the activities in the current course that use each outcome. One row per activity (table splits here)<br />
*Average: For each activity using the outcome, the average score is shown.<br />
*Number of grades: For each activity using the outcome, the number of grades is shown (non-graded participants are ignored)<br />
<br />
See [http://test.moodle.com/grade/report/outcomes/index.php?id=2 the test site] for a live demo of this report.<br />
<br />
=== Overview report ===<br />
Another basic report, showing a participant's course averages in each of the courses in which s/he has received grades.<br />
<br />
See [http://test.moodle.com/grade/report/overview/index.php the test site] for a live demo of this report.<br />
<br />
== Export plugins ==<br />
<br />
The API for these is extremely simple. Each export plugin should occupy a directory under /grade/export/xyz and needs to provide only an index.php file as a the primary interface. This file just accepts a 'courseid' parameter.<br />
<br />
== Import plugins ==<br />
<br />
Each import plugin should occupy a directory under /grade/import/xyz and needs to provide only an index.php file as a the primary interface. This file just accepts a 'courseid' parameter.<br />
<br />
The index.php will show an interface for further options and selections.<br />
<br />
Import plugin must validate data before starting the import operation, if some parts of import fail the user must be notified.<br />
<br />
Some sample import plugins are:<br />
<br />
===Import from CSV===<br />
<br />
Accepts an upload of (or URL to) a CSV file. Multiple options describe how to process the file, which columns to add etc. The imported grades always override current grades.<br />
<br />
===Import from XML===<br />
<br />
Accepts an upload of (or URL to) an XML file with this kind of format (from OU). <br />
<br />
<results batch="[someuniqueimportnumber]"><br />
<result><br />
<state>['new' or 'regrade']</state><br />
<assignment>[idnumber]</assignment><br />
<student>[studentid]</student><br />
<score>[score]</score><br />
</result><br />
<result><br />
<state>['new' or 'regrade']</state><br />
<assignment>[idnumber]</assignment><br />
<student>[studentid]</student><br />
<score>[score]</score><br />
</result><br />
[...]<br />
</results><br />
<br />
== Capabilities and Permissions ==<br />
<br />
* moodle/grade:view - view own grades or grades of other user if used in CONTEXT_USER<br />
<br />
* moodle/grade:viewall - view grades of all users<br />
<br />
* moodle/grade:viewhidden - see grades that are marked as hidden for the owner<br />
<br />
* moodle/grade:hide - be able to hide/unhide cells, items or categories<br />
<br />
* moodle/grade:lock - be able to lock cells, items or categories<br />
<br />
* moodle/grade:unlock - be able to unlock cells, items or categories<br />
<br />
* moodle/grade:manage - manage grade items and categories in gradebook (create, edit, lock, hide, delete, etc.)<br />
<br />
* moodle/grade:import - general import grades, requires separate permission for each plugin<br />
<br />
* moodle/grade:export - export grades, requires separate permission for each plugin<br />
<br />
* gradereport/grader:view - can view the grader report<br />
<br />
* gradeimport/csv:view - can view/use the csv import plugin<br />
<br />
* gradeexport/csv:view - can view/use the csv export plugin<br />
<br />
* moodle:site/accessallgroups<br />
<br />
== Development Tasks and Tracking ==<br />
<br />
For details of 1.9 development see [http://tracker.moodle.org/browse/MDL-9137 MDL-9137]<br />
<br />
For details of 2.0 development see [https://docs.moodle.org/en/Development:Gradebook_improvements Gradebook_imporovements] and [http://tracker.moodle.org/browse/MDL-19131 MDL-19131]<br />
<br />
==Updating module code==<br />
Module authors must implement new gradebook API and add upgrade code for migration of old grades into new gradebook. Fortunately the needed changes are not big.<br />
<br />
Steps:<br />
*add xxx_update_grades() function into mod/xxx/lib.php<br />
*add xxx_grade_item_update() function into mod/xxx/lib.php<br />
*patch xxx_update_instance(), xxx_add_instance() and xxx_delete_instance() to call xxx_grade_item_update()<br />
*patch all places of code that change grade values to call xxx_update_grades()<br />
*patch code that displays grades to students to use final grades from the gradebook<br />
<br />
There are many examples in official modules, assignment has the most advanced implementation.<br />
<br />
== Ideas for the future ==<br />
{{Moodle 2.0}}<br />
TODO: add new meta issue into tracker<br />
<br />
*option to aggregate including/excluding hidden grades - needs db changes<br />
*option to rollback all changes during import operation if anything fails<br />
*performance improvements<br />
*conditional activities<br />
*course completion criteria<br />
*better public API for modules<br />
*better API for gradebook plugins<br />
*better state tracking in export plugins<br />
*ajax reports<br />
*specialised reports<br />
*submission and marking date tracking db changes<br />
*calculation formula improvements<br />
*historical views<br />
*individual graph of grades (time vs %). Bar graph, lineal graph. Add (or not) the maximum posible; line of 0 (=minimum), 25, 50 (=median), 75 and 100 (=max) percentils of the group.<br />
*<br />
<br />
== See also ==<br />
<br />
* [http://moodle.org/mod/forum/discuss.php?d=69223&mode=3 Gradebook Development ideas] forum discussion<br />
* Using Moodle [http://moodle.org/mod/forum/discuss.php?d=51107 New gradebook for Moodle] forum discussion<br />
* [[Development:Gradebook Report Tutorial]]<br />
<br />
[[Category:Developer|Grades]]<br />
[[Category:Grades]]</div>Andyjdavishttps://docs.moodle.org/20/en/index.php?title=Development:Gradebook_improvements&diff=79034Development:Gradebook improvements2010-12-10T03:44:49Z<p>Andyjdavis: </p>
<hr />
<div>{{Work in progress}}<br />
{{Moodle 2.0}}Improving the usability of the Moodle gradebook is one of the main targets for Moodle 2.0 and 2.1.<br />
<br />
This evolving page summarises a number of proposed changes, derived from community suggestions in the [http://moodle.org/mod/forum/view.php?id=2122 Gradebook forum] and in the [http://tracker.moodle.org/secure/Dashboard.jspa tracker], with special attention given to [http://tracker.moodle.org/browse/MDL/component/10062?selected=com.atlassian.jira.plugin.system.project:component-popularissues-panel the issues with the most votes].<br />
<br />
We would really like your feedback on:<br />
<br />
# The changes already proposed here<br />
# Any issues that you feel are not yet addressed<br />
<br />
We would also like your contributions to [[Gradebook uses]].<br />
<br />
Please join the discussions and post your suggestions in the [http://moodle.org/mod/forum/view.php?id=2122 Gradebook forum].<br />
<br />
<br />
==Stage 1==<br />
[[Image:Edit categories and items.png|thumb|Edit categories and items advanced settings]]<br />
''May 2009 progress update: Stage 1 has now been completed, with improvements implemented in Moodle 1.9.5 and 2.0. See [[Gradebook improvements in Moodle 1.9.5]] for details.''<br />
<br />
===Easier editing of categories and items===<br />
<br />
* MDL-16913 New "Edit categories and items" page, with hide/show advanced settings, moving of multiple items between categories and quick editing of multiple settings<br />
* MDL-17829 Combine category grade item and category edit forms<br />
<br />
===Report improvements===<br />
[[Image:Simple_grader_report_scroll.jpg|thumb|Simple grader report from LSU]]<br />
* MDL-18228 Add horizontal scrollbar in grader report to scroll grades while students stay fixed (as used in the LSU [[grade/report/simple grader/index|simple grader report]])<br />
* MDL-17991 New visual organization for gradebook user report (including category nesting, ranges)<br />
[[Image:User report.png|thumb|User report]]<br />
===Better gradebook navigation===<br />
<br />
* MDL-18004 Implement tabs navigation<br />
* MDL-12631 Grader report breadcrumbs are too long<br />
<br />
===Simplifying the gradebook===<br />
<br />
* MDL-18321 Change gradereport/overview:view default setting to 'Not set' for the role of teacher and non-editing teacher in new installs<br />
* [[Simplifying the gradebook by changing permissions]] - documentation on how to provide a simplified gradebook for teachers by changing certain permissions<br />
* MDL-12380 Add an admin setting for selecting which aggregation types are available<br />
* MDL-18523 Only display the 'Synchronise legacy grades' button when necessary<br />
<br />
===Groups access===<br />
<br />
* MDL-18119 Restrict teachers to their own groups when accessing User Reports<br />
* MDL-15617 Showing all groups in gradebook when user restricted to one<br />
<br />
===Further bug fixes and improvements===<br />
<br />
* MDL-14961 Adding a help button next to the "Synchronise legacy grades"<br />
* MDL-13417 Outcomes report is available even when outcomes are disabled<br />
* MDL-12380 Allow grades over 100%<br />
* MDL-14831, MDL-15033 and MDL-16363 Issues relating to the "Sum of grades" aggregation type<br />
<br />
==Stage 2==<br />
''Nov 2010 progress update: Stage 2 has now been completed, with improvements implemented in 2.0. Items that were not completed have been bumped to stage 3 (Moodle 2.1)''<br />
<br />
For more details about these items see MDL-19131 Gradebook 2.0 - META.<br />
<br />
===Centralisation of grade item settings in gradebook===<br />
* MDL-19133 Module forms remain the same, but they draw their "Grade" section from gradebook code<br />
<br />
===Gradebook help===<br />
<br />
* Review current [[Gradebook help files]] and check for consistency<br />
* MDL-13960 Make full use of title attributes in the gradebook<br />
<br />
==Stage 3==<br />
For more details about these items see MDL-25423 Gradebook 2.1 - META. <br />
<br />
===Simplifying the gradebook further===<br />
<br />
* MDL-18049 Investigate ways of reducing the number of settings in the gradebook. Currently only grade category settings can be forced and hidden by an admin. See [[Development:Gradebook settings review]].<br />
* MDL-20250 Add admin settings for disabling gradebook features such as multiplicator, offset, calculations<br />
<br />
===Outcomes===<br />
<br />
* Review outcomes and how they are implemented in the gradebook. MDL-10685 is part of this.<br />
* MDL-16103 Have an icon for outcomes on the edit categories and items page<br />
<br />
===Centralisation of grade item settings in gradebook===<br />
* Hide, Lock, Maximum Grade and other grade item settings in module forms are saved in the gradebook tables, not in module tables<br />
<br />
===Scales Refactoring===<br />
* MDL-17258 Custom non-numeric scales to have assigned numeric value in gradebook<br />
<br />
==Further changes under consideration==<br />
[[Image:Continuous grade distribution.png|thumb|Animated grade statistics report]]<br />
[[Image:Simple_grader_quick_edit_student.png|thumb|Student grades quick edit from LSU]]<br />
* MDL-15050 Grades entered in 1.9 gradebook should show in student activity report<br />
* MDL-13501 [[Student projects/Animated grade statistics report|Animated grade statistics report]] (GSoC project by Daniel Servos)<br />
* MDL-12203 Bulk message direct from the gradebook<br />
* MDL-18229 Add grade item and student grades quick edit feature to the grader report (with thanks to developers at the LSU for their [[grade/report/simple grader/quick edit|quick edit screens]])<br />
* MDL-18163 Provide summary statistics in the gradebook<br />
* MDL-16801 Create a grade history GUI<br />
* MDL-25424 Provide a reason why a category/course total is not being displayed<br />
<br />
==See also==<br />
*[[Gradebook uses]]<br />
*[[Gradebook improvements in Moodle 1.9.5]]<br />
*[[Development talk:Gradebook improvements]]<br />
*[[Development:Gradebook settings review]]<br />
* MDL-18083 META: Gradebook improvements - Stage 1<br />
* MDL-19131 Gradebook 2.0 - META<br />
* MDL-20249 Gradebook 1.9.6 - META<br />
*[[Development:Grades]] for archive specification<br />
<br />
[[Category:Grades]]<br />
[[Category:Developer]]</div>Andyjdavishttps://docs.moodle.org/20/en/index.php?title=Development:Grades&diff=79033Development:Grades2010-12-10T03:44:05Z<p>Andyjdavis: /* Executive Summary */</p>
<hr />
<div>{{Work in progress}}<br />
<br />
== Executive Summary ==<br />
<br />
Not that this document primarily describes the current workings of the gradebook. For more detailed information about current development within the gradebook see [[Development:Gradebook_improvements]]<br />
<br />
The gradebook mechanisms must be rebuilt to:<br />
<br />
# '''Improve performance and scalability''' - All grades from throughout the system will be pushed to a central system of tables. This means reports based on grades can be generated much faster, and the gradebook has ultimate control over the content.<br />
# '''Improve flexibility''' - All aspects of the new gradebook will use simple plugin structures, namely: exports, imports and displays/reports. It is expected that the community will be very active in producing [[Development:Gradebook Report Tutorial |special-purpose reports]] analysing the basic grade data in new ways, for example, or writing plugins to transfer grades to student information systems.<br />
# '''Allow rubrics for outcomes (aka standards,competencies,goals)''' - As well as numerical grades, each grading item can consist of a number of scores made on a rubric against a standard outcome statement. These can be automatically converted to a numerical grade if desired or just shown as is.<br />
# '''Allow arbitrary columns and derived columns''' - Arbitrary columns of data can be added (either manually or via import). Columns can also be automatically filled based on formulas.<br />
# '''Implement limited public API''' - Activities may use this API to send grades/outcomes to gradebook and find out the final grades.<br />
<br />
== Glossary ==<br />
<br />
Here are some terms used in the gradebook, both in the development and the user interface. Using these terms in discussions about the gradebook will help to reduce confusion.<br />
<br />
{| class="nicetable"<br />
!Term<br />
!Definition<br />
|-<br />
|Activity<br />
|An instance of an activity module [[Category:Modules|Module]] (e.g. a single quiz, assignment etc...)<br />
|-<br />
|Calculation<br />
|A formula used to calculate grades, based (optionally) on other grade items. Not the same as [[Calculated_question_type|Calculated question types]].<br />
|-<br />
|Category<br />
|A set of Grade Items. A Category also has its own aggregated Grade which is calculated from its Grade Items. There is no limit to the level of nesting of Categories (a Category may belong to another Category). However, each Grade Item may belong to only one Category. <br />
|-<br />
|Course completion<br />
|The concept of meeting certain criteria for completing a course. In the context of the gradebook, this means a set of grades that must be reached, or a number of outcomes/competencies to complete/master.<br />
|-<br />
|Grade<br />
|A Grade is a single assessment. It may be a number or an item on a scale (possibly tied to an Outcome). Raw grade value is the numerical or scale grade from activity. Final grade is the grade reported in gradebook.<br />
|-<br />
|[[Gradebook|Gradebook]]<br />
|A central location in Moodle where students' Grades are stored and displayed. Teachers can keep track of their students' progress and organise which set of Grades their students will be able to see. Students see their own Grades.<br />
|-<br />
|Grade Item<br />
|A "column" of Grades. It can be created from a specific Activity or other module, calculated from other Grade Items, or entered manually.<br />
|-<br />
|[[Development:Grades#Locked_grades|Grade Locks]]<br />
|See linked section of this page<br />
|-<br />
|History<br />
|The gradebook has its own type of log, which keeps a History of all changes made to grades.<br />
|-<br />
|[[Development:Outcomes|Outcome]]<br />
|[[Development:Outcomes|Outcomes]] are specific descriptions of what a person is expected to be able to do or understand at the completion of an activity or course. An activity might have more than one outcome, and each may have a grade against it (usually on a scale). Other terms for Outcomes are ''Competencies'' and ''Goals''. See some [[Development:Outcomes_examples|Examples]].<br />
|-<br />
|[[Scales|Scale]]<br />
|A scale is a set of responses from which the teacher can choose one. eg Very cool, Cool, Fairly cool, Not very cool, Not cool<br />
|-<br />
|Letter Grades<br />
|Special representation of grade values similar to scales. Letters are configured in course contexts or above and are defined by lower boundary. eg A (above 90 %), B (above 80 %), C (above 70 %), D (above 50 %), F (above 0 %)<br />
<br />
|}<br />
<br />
== Database structures ==<br />
=== grade_items ===<br />
<br />
This table keeps information about gradeable items (ie columns). If an activity (eg an assignment or quiz) has multiple grade_items associated with it (eg several outcomes and numerical grade), then there will be a corresponding multiple number of rows in this table.<br />
<br />
idnumber is a tag unique inside a course identifying the grade item, useful for identifying data in exports and for referring to the grade item in calculations. It is the same as the idnumber in course_modules.<br />
<br />
<br />
{| border="1" cellpadding="2" cellspacing="0"<br />
|'''Field''' <br />
|'''Type''' <br />
|'''Default''' <br />
|'''Info''' <br />
|-<br />
|'''id''' <br />
|int(10) <br />
|<br />
|autoincrementing <br />
|-<br />
|'''courseid''' <br />
|int(10) <br />
|<br />
|The course this item is part of <br />
|-<br />
|'''categoryid''' <br />
|int(10) <br />
|<center>NULL</center> <br />
|the category group this item belongs to <br />
|-<br />
|itemname <br />
|varchar(255) <br />
|<center>NULL</center> <br />
|The name of this item (pushed in by the module or entered by user) <br />
|-<br />
|'''itemtype''' <br />
|varchar(30) <br />
|<br />
|'mod', 'blocks', 'manual', 'course', 'category' etc <br />
|-<br />
|itemmodule <br />
|varchar(30) <br />
|<center>NULL</center> <br />
|'forum', 'quiz', 'csv', etc <br />
|-<br />
|iteminstance <br />
|int(10) <br />
|<center>NULL</center> <br />
|id of the item module <br />
|-<br />
|itemnumber <br />
|int(10) <br />
|<center>NULL</center> <br />
|Can be used to distinguish multiple grades for an activity <br />
|-<br />
|iteminfo <br />
|text <br />
|<center>NULL</center> <br />
|Info and notes about this item XXX <br />
|-<br />
|'''idnumber'''<br />
|varchar(255) <br />
|<center>NULL</center> <br />
|Arbitrary idnumber provided by the module responsible (optional and course unique)<br />
|-<br />
|calculation <br />
|text<br />
|<center>NULL</center> <br />
|Spreadsheet-type formula used to process the raw grades into final grades<br />
|-<br />
|'''gradetype''' <br />
|int(4) <br />
|<center>1</center> <br />
|0 = none, 1 = value, 2 = scale, 3 = text <br />
|-<br />
|grademax <br />
|float(10,5) <br />
|<center>100</center> <br />
|What is the maximum allowable grade? <br />
|-<br />
|grademin <br />
|float(10,5) <br />
|<center>0</center> <br />
|What is the minimum allowable grade? <br />
|-<br />
|'''scaleid''' <br />
|int(10) <br />
|<center>NULL</center> <br />
|If this grade is based on a scale, which one is it? <br />
|-<br />
|'''outcomeid''' <br />
|int(10) <br />
|<center>NULL</center> <br />
|If this is outcome item, which outcome is it? <br />
|-<br />
|gradepass<br />
|float(10,5) <br />
|<center>0</center> <br />
|What grade is needed to pass? grademin <= gradepass <= grademax<br />
|-<br />
|multfactor <br />
|float(10,5) <br />
|<center>1.0</center> <br />
|Multiply all raw grades from activities by this <br />
|-<br />
|plusfactor <br />
|float(10,5) <br />
|<center>0.0</center> <br />
|Add this to all raw grades from activities by this <br />
|-<br />
|aggregationcoef <br />
|float(10,5) <br />
|<center>0.0</center> <br />
|Weight applied to all grades in this grade item during aggregation with other grade items.<br />
|-<br />
|sortorder <br />
|int(10) <br />
|<center>0</center> <br />
|Sorting order of the columns (pre-order walk of the grading tree)<br />
|-<br />
|display<br />
|int(10) <br />
|<center>0</center> <br />
|Display as real grades, percentages (in reference to the minimum and maximum grades) or letters (A, B, C etc..), or course default (0)<br />
|-<br />
|hidden <br />
|int(10) <br />
|<center>0</center> <br />
|1 is hidden, 1 is hide always, > 1 is a date to hide until (prevents viewing of all user grades) <br />
|-<br />
|'''locked'''<br />
|int(10) <br />
|<center>0</center> <br />
|0 is not locked, > 0 is a date when was item locked (no final grade or grade_item updates possible)<br />
|-<br />
|'''locktime'''<br />
|int(10) <br />
|<center>0</center> <br />
|0 no auto locking, > 0 is a date to lock grade item and final grades after automatically <br />
|-<br />
|deleted <br />
|int(10) <br />
|<center>0</center> <br />
|1 means the associated module instance has been deleted<br />
|-<br />
|'''needsupdate'''<br />
|int(10) <br />
|<center>0</center> <br />
|If this flag is set, then the whole column will be recalculated. If set in course item, some other item needs recalculation. Calculated and category items are recalculated together with any other items.<br />
|-<br />
|timecreated <br />
|int(10)<br />
|<br />
|The first time this grade_item was created<br />
|-<br />
|timemodified <br />
|int(10)<br />
|<br />
|The last time this grade_item was modified<br />
|}<br />
<br />
=== grade_categories ===<br />
<br />
This table keeps information about categories, used for grouping items. An associated grade_item will be maintained for each category to store the aggregate data.<br />
<br />
{| border="1" cellpadding="2" cellspacing="0"<br />
|'''Field''' <br />
|'''Type''' <br />
|'''Default''' <br />
|'''Info''' <br />
|-<br />
|'''id''' <br />
|int(10) <br />
|<br />
|autoincrementing <br />
|-<br />
|'''courseid''' <br />
|int(10) <br />
|<br />
|The course this grade category is part of <br />
|-<br />
|'''parent''' <br />
|int(10) <br />
|<center>NULL</center> <br />
|Parent grade_category (hierarchical)<br />
|-<br />
|depth<br />
|int(10) <br />
|<center>0</center> <br />
|How deep is this category from the highest level (1,2,3)<br />
|-<br />
|path<br />
|varchar(255) <br />
| <br />
|Shows the path as /1/2/3/ <br />
|-<br />
|fullname <br />
|varchar(255) <br />
|<br />
|The name of this grade category <br />
|-<br />
|aggregation <br />
|int(10) <br />
|<center>0</center> <br />
|A constant pointing to one of the predefined aggregation strategies (none, mean,median,sum, etc) <br />
|-<br />
|keephigh <br />
|int(10) <br />
|<center>0</center> <br />
|Keep only the X highest items <br />
|-<br />
|droplow <br />
|int(10) <br />
|<center>0</center> <br />
|Drop the X lowest items <br />
|-<br />
|aggregateonlygraded<br />
|int(1) <br />
|<center>0</center> <br />
|Aggregate only existing grades <br />
|-<br />
|aggregateoutcomes<br />
|int(1) <br />
|<center>0</center> <br />
|Aggregate otcomes together with normal items <br />
|-<br />
|aggregatesubcats<br />
|int(1) <br />
|<center>0</center> <br />
|Aggregate only items placed directly in category or all items in subcategories excluding the subcategory totals <br />
|-<br />
|timecreated<br />
|int(10) <br />
|<br />
|The first time this grade_category was created<br />
|-<br />
|timemodified <br />
|int(10) <br />
|<br />
|The last time this grade_category was modified<br />
|}<br />
<br />
=== grade_grades ===<br />
<br />
This table keeps individual grades for each user and each item. The raw grade is exactly as imported or submitted by modules. The rawgrademax/min and rawscaleid are stored here to record the values at the time the grade was stored, because teachers might change this for an activity! All the results are normalised/resampled/calculated for the finalgrade, which is relative to the max/min/scaleid values stored in the grade_item. The finalgrade field is effectively a cache and values are rebuilt whenever raw values or the grade_item changes.<br />
<br />
Note that the finalgrade for a scale-based item may be non-integer! It needs to be rounded on display.<br />
<br />
{| border="1" cellpadding="2" cellspacing="0"<br />
|'''Field''' <br />
|'''Type''' <br />
|'''Default''' <br />
|'''Info''' <br />
|-<br />
|'''id''' <br />
|int(10) <br />
|<br />
|autoincrementing <br />
|-<br />
|'''itemid''' <br />
|int(10) <br />
|<br />
|The item this grade belongs to <br />
|-<br />
|'''userid''' <br />
|int(10) <br />
|<br />
|The user who this grade is for <br />
|-<br />
|rawgrade<br />
|float(11,10) <br />
|<center>NULL</center> <br />
|The raw grade that came into the system<br />
|-<br />
|rawgrademax <br />
|float(11,10) <br />
|<center>100</center> <br />
|The maximum allowable grade when this was created <br />
|-<br />
|rawgrademin <br />
|float(11,10) <br />
|<center>0</center> <br />
|The minimum allowable grade when this was created <br />
|-<br />
|'''rawscaleid''' <br />
|int(10) <br />
|<center>NULL</center> <br />
|If this grade is based on a scale, which one was it? <br />
|-<br />
|'''usermodified'''<br />
|int(10) <br />
|<center>NULL</center> <br />
|the userid of the person who last modified the raw grade value<br />
|-<br />
|finalgrade<br />
|float(11,10) <br />
|<center>NULL</center> <br />
|The final grade (cached) after all calculations are made. Overriden grades are also stored here.<br />
|- <br />
|hidden <br />
|int(10) <br />
|<center>0</center> <br />
|0 is not hidden, 1 is hide always, > 1 is a date to hide until <br />
|-<br />
|'''locked'''<br />
|int(10) <br />
|<center>0</center> <br />
|0 is not locked, > 0 when was the grade locked<br />
|-<br />
|'''locktime'''<br />
|int(10) <br />
|<center>0</center> <br />
|0 is never, > 0 is a date to lock the final grade after automatically<br />
|-<br />
|exported <br />
|int(10) <br />
|<center>0</center> <br />
|0 is not exported, > 0 is the last exported date <br />
|-<br />
|excluded <br />
|int(10) <br />
|<center>0</center> <br />
|grade excluded from aggregation, > 0 is the last exported date <br />
|-<br />
|overridden <br />
|int(10) <br />
|<center>0</center> <br />
|0 is not overridden, > 0 is the last overridden date <br />
|-<br />
|feedback <br />
|text <br />
|<center>NULL</center> <br />
|Manual feedback from the teacher. Could be a code like 'mi'. <br />
|-<br />
|feedbackformat<br />
|int(10)<br />
|<center>0</center> <br />
|Text format for feedback<br />
|-<br />
|information <br />
|text <br />
|<center>NULL</center> <br />
|not sued yet (Further information like forum rating distribution 4/5/7/0/1 ?)<br />
|-<br />
|informationformat<br />
|int(10)<br />
|<center>0</center> <br />
|Text format for information<br />
|-<br />
|timecreated<br />
|int(10) <br />
|<br />
|temporary hack - the date of submission in activity if any, new field expected in 2.0<br />
|-<br />
|timemodified<br />
|int(10) <br />
|<br />
|temporary hack - the date of grading in activity or date of manual grading in gradebook, new field expected in 2.0<br />
|}<br />
<br />
=== grade_outcomes ===<br />
<br />
This table describes the outcomes used in the system. An outcome is a statement tied to a rubric scale from low to high, such as “Not met, Borderline, Met” (stored as 0,1 or 2). For more info about these see [[Development:Outcomes]].<br />
<br />
{| border="1" cellpadding="2" cellspacing="0"<br />
|'''Field''' <br />
|'''Type''' <br />
|'''Default''' <br />
|'''Info''' <br />
<br />
|-<br />
|'''id''' <br />
|int(10) <br />
|<br />
|autoincrementing <br />
<br />
|-<br />
|'''courseid''' <br />
|int(10) <br />
|<center>NULL</center> <br />
|Mostly these are defined site wide ie NULL <br />
<br />
|-<br />
|shortname <br />
|varchar(255) <br />
|<br />
|The short name or code for this outcome statement <br />
<br />
|-<br />
|fullname <br />
|text <br />
|<br />
|The full description of the outcome (usually 1 sentence) <br />
<br />
|-<br />
|'''scaleid''' <br />
|int(10) <br />
|<br />
|The recommended scale for this outcome. <br />
|-<br />
|description <br />
|text <br />
|<center>NULL</center> <br />
|The full description of the outcome (usually 1 sentence) <br />
|-<br />
|timecreated<br />
|int(10) <br />
|<br />
|the time this outcome was first created <br />
<br />
|-<br />
|timemodified<br />
|int(10) <br />
|<br />
|the time this outcome was last updated <br />
<br />
|-<br />
|'''usermodified'''<br />
|int(10) <br />
|<center>NULL</center> <br />
|the userid of the person who last modified this outcome<br />
|}<br />
<br />
=== grade_outcomes_courses ===<br />
An intersection table used to make standard outcomes available to courses.<br />
<br />
{| border="1" cellpadding="2" cellspacing="0"<br />
|'''Field''' <br />
|'''Type''' <br />
|'''Default''' <br />
|'''Info''' <br />
<br />
|-<br />
|'''id''' <br />
|int(10) <br />
|<br />
|autoincrementing <br />
<br />
|-<br />
|'''courseid'''<br />
|int(10)<br />
|<br />
|The id of the course being assigned the outcome<br />
<br />
|-<br />
|'''outcomeid''' <br />
|int(10) <br />
|<br />
|The id of the outcome being assigned to the course<br />
|}<br />
<br />
=== grade_import_newitem ===<br />
<br />
{| border="1" cellpadding="2" cellspacing="0"<br />
|'''Field''' <br />
|'''Type''' <br />
|'''Default''' <br />
|'''Info''' <br />
<br />
|-<br />
|'''id''' <br />
|int(10) <br />
|<br />
|autoincrementing <br />
<br />
|-<br />
|itemname<br />
|varchar(255)<br />
|<br />
|*TODO* Document<br />
<br />
|-<br />
|importcode<br />
|int(12) <br />
|<br />
|*TODO* Document <br />
|}<br />
<br />
=== grade_import_values ===<br />
<br />
{| border="1" cellpadding="2" cellspacing="0"<br />
|'''Field''' <br />
|'''Type''' <br />
|'''Default''' <br />
|'''Info''' <br />
<br />
|-<br />
|'''id''' <br />
|int(10) <br />
|<br />
|autoincrementing <br />
<br />
|-<br />
|'''itemid''' <br />
|int(10) <br />
|NULL<br />
|*TODO* Document <br />
<br />
|-<br />
|newgradeitem<br />
|int(10)<br />
|NULL<br />
|*TODO* Document<br />
<br />
|-<br />
|'''userid''' <br />
|int(10) <br />
|<br />
|*TODO* Document <br />
<br />
|-<br />
|finalgrade<br />
|float(10,5) <br />
|NULL<br />
|*TODO* Document <br />
<br />
|-<br />
|feedback<br />
|text<br />
|NULL<br />
|*TODO* Document <br />
<br />
|-<br />
|importcode<br />
|int(12) <br />
|<br />
|*TODO* Document <br />
|}<br />
<br />
=== History tables ===<br />
<br />
These table keep track of changes to most of the grade tables. Using these it should be possible to reconstruct the grades at any point in time in the past, or to audit grade changes over time. It should be quicker to use these tables for that, rather than storing this information in the main Moodle log. The following tables are set up for that purpose:<br />
<br />
#grade_categories_history<br />
#grade_grades_history<br />
#grade_items_history<br />
#grade_outcomes_history<br />
<br />
Each of them has exactly the same DB structure as their matching table (e.g. grade_categories), with 3 extra fields:<br />
<br />
<br />
<br />
{| border="1" cellpadding="2" cellspacing="0"<br />
|'''Field''' <br />
|'''Type''' <br />
|'''Default''' <br />
|'''Info''' <br />
<br />
|-<br />
|action<br />
|int(10) <br />
|0<br />
|The action that lead to the change being recorded (insert, update, delete)<br />
<br />
|-<br />
|'''oldid''' <br />
|int(10) <br />
|<br />
|The id of the record being changed or inserted (PK of the main table, not the history table) <br />
<br />
|-<br />
|source<br />
|varchar(255)<br />
|NULL<br />
|The module from which the action originated <br />
|}<br />
<br />
=== grade_letters ===<br />
<br />
{| border="1" cellpadding="2" cellspacing="0"<br />
|'''Field''' <br />
|'''Type''' <br />
|'''Default''' <br />
|'''Info''' <br />
<br />
|-<br />
|'''id''' <br />
|int(10) <br />
|<br />
|autoincrementing <br />
<br />
|-<br />
|contextid<br />
|int(10)<br />
|<br />
|What contextid does this letter apply to (from levels CONTEXT_SYSTEM, CONTEXT_COURSECAT or CONTEXT_COURSE)<br />
<br />
|-<br />
|lowerboundary<br />
|float(10,5) <br />
|<br />
|The lower boundary of the letter. Its upper boundary is the lower boundary of the next highest letter, unless there is none above, in which case it's grademax for that grade_item.<br />
<br />
|-<br />
|letter<br />
|varchar(255) <br />
|<br />
|The display value of the letter. Can be any character or string of characters (OK, A, 10% etc..) <br />
|}<br />
<br />
== Overview of module communication ==<br />
<br />
Modules usually store raw grades internally and pass them into gradebook every time they change. Gradebook may also request activities to resend the grades. <br />
<br />
The gradebook is designed to be as separate as possible from the code of activities - modules do not read grade tables or use internal gradebook API. <br />
<br />
Originally it was planned to use new events API, but in the end it was decided to use minimal API consisting of several function in lib/gradelib.php and each mod/xxx/lib.php<br />
<br />
=== Backward compatibility with Moodle 1.8 and earlier ===<br />
<br />
Function grade_grab_legacy_grades($courseid) may be used to request transfer of grades from legacy or 3rd party activities which were not yet converted to new grade API. This function is not called automatically.<br />
<br />
Modules are responsible to push existing grades into gradebook during upgrade.<br />
<br />
==API for communication with modules/blocks==<br />
<br />
Modules may use only functions from lib/gradelib.php which are marked as public. This API may be extended in later 1.9.x release. Activities should access/update only own grades.<br />
<br />
===grade_get_grades()===<br />
<br />
grade_get_grades($courseid, $itemtype, $itemmodule, $iteminstance, $userid_or_ids=0)<br />
<br />
Returns grading information for given activity - optionally with users grades. Manual, course or category items can not be queried.<br />
<br />
===grade_get_outcomes()===<br />
<br />
grade_get_outcomes($courseid, $itemtype, $itemmodule, $iteminstance,$userid=0)<br />
<br />
Returns list of outcomes used in course together with current outcomes for this user.<br />
<br />
===grade_is_locked()===<br />
<br />
eg grade_is_locked($courseid, $itemtype, $itemmodule, $iteminstance, $itemnumber, $userid=NULL)<br />
<br />
This function will tell a module whether a grade (or grade_item if $userid is not given) is currently locked or not. If it's locked to the current user then the module can print a nice message or prevent editing in the module. If no $userid is given, the method will always return the grade_item's locked state. If a $userid is given, the method will first check the grade_item's locked state (the column). If it is locked, the method will return true no matter the locked state of the specific grade being checked. If unlocked, it will return the locked state of the specific grade.<br />
([http://moodle.org/mod/forum/discuss.php?d=69223#p311329 info])<br />
<br />
===grade_update()===<br />
<br />
grade_update($source, $courseid, $itemtype, $itemmodule, $iteminstance, $itemnumber, $grades=NULL, $itemdetails=NULL)<br />
<br />
Submit new or update grade; update/create grade_item definition. Grade must have userid specified, rawgrade and feedback with format are optional. rawgrade NULL means 'Not graded', missing property or key means do not change existing. Only following grade item properties can be changed 'itemname', 'idnumber', 'gradetype', 'grademax', 'grademin', 'scaleid', 'multfactor', 'plusfactor', 'deleted'.<br />
<br />
===grade_update_outcomes()===<br />
<br />
grade_update_outcomes($source, $courseid, $itemtype, $itemmodule, $iteminstance, $userid, $data)<br />
<br />
Updates outcomes of a given user. Manual outcomes cannot be updated.<br />
<br />
== Private gradebook API ==<br />
Private API is used by gradebook plugins and core Moodle code, it may change in 2.0. Most of the interesting classes and functions are in lib/gradelib.php, grade/lib.php and grade/report/lib.php.<br />
<br />
The following 3 functions are all in /lib/gradelib.php<br />
<br />
===grade_regrade_final_grades()===<br />
<br />
grade_regrade_final_grades($courseid=NULL, $userid=NULL, $updated_item=NULL)<br />
<br />
Updates all grade_grades->finalgrade records for each grade_item matching the given attributes. The search is further restricted, so that only grade_items that have needs_update == true or that use calculation are retrieved and used for the update. The function returns the number of grade_items updated (NOT the same as the number of grades_grades updated!).<br />
<br />
===grade_verify_idnumber()===<br />
<br />
grade_verify_idnumber($idnumber, $grade_item = null, $cm = null, $gradeitem)<br />
<br />
Verify new value of idnumber - checks for uniqueness of new idnubmers, existing are kept intact.<br />
<br />
===remove_course_grades()===<br />
<br />
remove_course_grades($courseid, $showfeedback)<br />
<br />
Remove all grade related course data - history is kept<br />
<br />
<br />
TODO: add description of the other methods and classes + simple usage examples + querylib.php description<br />
<br />
== Dealing with multiple grades ==<br />
<br />
Modules usually produce only one grade item per activity. Optionally one or more outcomes may be attached to activities.<br />
<br />
Some activities may need to aggregate multiple ratings or attempts before sending them into the gradebook. Activities can not send variable number of items.<br />
<br />
If the gradebook receives multiple grade items from a module, then they are automatically grouped together in a unique grade category (with the same name as the module instance). See [[Development:Outcomes]] for more details.<br />
<br />
TODO: this may still be changed<br />
<br />
== Calculated grade items ==<br />
<br />
Categories or manual items maybe calculated using spreadsheet-like formulas. Formulas may reference other items from the same course only using Id numbers in double square brackets.<br />
<br />
eg: <nowiki>= MEAN([[quiz121]], [[quizend]]) + [[assignmentAXC]] + 20.0</nowiki><br />
<br />
== Regrading / updating of final grades ==<br />
<br />
TODO: describe needsupdate flag and incremental updates<br />
<br />
== Adjustment of raw grades ==<br />
Grade_item contains optional rules for adjusting the raw grade before it is cached into a final grade. These rules are processed BEFORE the calculation discussed above. Scale is never changed. Multfactor and plusfactor may be used to alter raw grades coming from activities, but it is recommended to use formulas instead.<br />
<br />
== Displaying the grades to ordinary participants ==<br />
<br />
The module takes responsibility for displaying grades within the module (to a student, say). It is recommended to use the real final grades obtained using grade_get_grades() functionBecause guidebook might force hiding, override grade, etc.<br />
<br />
For full display of grades in a whole course say, the student uses the same link as teachers use to access the gradebook. However, due to their different permissions they will only have access to specific reports. By default this is the ''User report'' report which only shows their own grades and has very few configuration options.<br />
<br />
== Locked grades ==<br />
<br />
Both whole columns and individual grades can be locked in the gradebook, via the ''locked'' field. Teachers may want to do this to prevent further changes from the modules, or from other teachers. When a grade is locked, any changes that might affect that grade are ignored. When the graded is unlocked, activities are asked to resend the latest grades.<br />
<br />
In the main GUIs the lock toggling will be achieved by clicking on a little padlock icon beside each entry or column.<br />
<br />
There is also an option to lock grade or item after some specified date.<br />
<br />
== Overridden grades ==<br />
<br />
Grades can be manually modified (overridden) in the gradebook. When this is done the entered value is always used instead of the aggregated, calculated or activity grade.<br />
<br />
Once grades have been overriden in the gradebook they become read only in the original module. The module should provide a visual indication as to why the grade cannot be modified.<br />
<br />
The need to improve how the module expresses that a grade has been overridden will be reduced by the new [https://docs.moodle.org/en/Development:Grading_interface_2.0 grading interface]<br />
<br />
== Hidden grades and categories ==<br />
<br />
Grades and categories can be hidden in the gradebook or the "categories and items" screen. When a category is hidden all the grade items within it are automatically hidden as well. When a category is un-hidden then all the grade items within it are un-hidden.<br />
<br />
The teacher always sees totals calculated from all relevant items (hidden or un-hidden)<br />
<br />
(Features below were added in 1.9.8 and 2.0)<br />
<br />
When a grade is shown its parent category will also be shown if it was hidden. MDL-21367<br />
<br />
The teacher decides what ordinary users can see in the case of totals that include hidden grades (MDL-21218, in 1.9.8 and 2.0). The user and overview report each have a setting to choose between:<br />
<br />
# Hide any totals that are dependent on a hidden item (show a hyphen there) [DEFAULT]<br />
# Display totals excluding the hidden items<br />
# Display full totals including the hidden items (may allow students to back-calculate hidden grades)<br />
<br />
== Logging ==<br />
<br />
All grading related changes maybe logged in history tables.<br />
<br />
== Security Issues ==<br />
<br />
For security an option to force SSL for the gradebook might be good.<br />
<br />
==Overall grade==<br />
<br />
Each course has exactly one course grade item. It may be used for this purpose now. Other course completion criteria will be implemented in 2.0.<br />
<br />
== Report plugins ==<br />
All the main interface of the gradebook are implemented as report plugins. Each plugin is fully responsible for page layout, there are some handy functions in grade/lib.php. They can even define their own capabilities and extra tables if the core tables are not enough, as they'll have a full /grade/report/xxxx/db directory.<br />
<br />
Each report defines one capability to allow people to see that report, so that admins have control over who can see what reports. For example, the participant interface can be a totally separate report plugin.<br />
<br />
This allows for the widest flexibility and safety in how grades are presented.<br />
<br />
=== Default teacher interface ===<br />
This interface will be what teachers see by default, and will subsume everything the current interface (in Moodle 1.8) does.<br />
<br />
Some snippets of functionality:<br />
{{Moodle 1.9}}<br />
Overall it's a grid, with participant names down one side and grade items along the top. <br />
<br />
Columns will be able to be collapsed together by grouping them into categories. Grades for categories can be calculated via various means. <br />
<br />
“Eye-cons” on the columns and checkboxes by every grade (this bit possibly controlled with a switch) allow hiding by category, by column, by individual grade.<br />
<br />
Textual notes can be added to each grade for more info. These show up to participants as well.<br />
<br />
A groups menu allows the teacher to switch between showing EACH of the groups they have access to, or ALL the groups they have access to.<br />
<br />
All grade items will link to modulepath/grade.php?id=44 which will work out what the current person should be allowed to see and either redirect them to the correct page or just show them immediately. This copes with situations like the quiz, say, where we want editing teachers to go to the detailed reports there while participants just see their own grade or whatever the quiz is set to show.<br />
<br />
User preference to SWITCH between showing raw grades, percentage grades, or both, or grade letters (A/B/C etc). <br />
<br />
Settings for grade letters not only define the transformation from percentage to grades, but also the transformation from letters to grades (in case the teacher edits some of the letter grades).<br />
<br />
Categories are shown above the headings for each column. Clicking for more info on a category will just show the category with a summary column showing total/average for just that category (PLUS the summary column for the whole course).<br />
<br />
All columns should be sortable up/down.<br />
<br />
At the bottom of each column is a row with the mean course score. If in groups mode, then add ANOTHER row with just the group mean. Add the number of grades used in brackets. eg 56% (11). When the report is paged, these means are still for the whole course/group (not the page!)<br />
<br />
{{Moodle 2.0}}<br />
<br />
Teachers can type “straight into” the grid using AJAX or fallback to forms. No popup menus for values.<br />
<br />
Later on we can support customisable shorthand codes to make data entry quick (eg type 'ab' for absent, or 'nge' for not good enough).<br />
<br />
See [http://test.moodle.com/grade/report/grader/index.php?id=2 the test site] for a live demo of this report.<br />
<br />
=== Default participant interface ===<br />
This interface will be what participants see by default:<br />
<br />
Some snippets of functionality:<br />
<br />
*Invert the grid to show one item per row, with the total/average at the bottom.<br />
*Use second/third columns to show categories.<br />
*Include ranking score in another column.<br />
*Show feedback<br />
*Show percentage<br />
*No editing functionality.<br />
<br />
See [http://test.moodle.com/grade/report/user/index.php?id=2 the test site] for a live demo of this report.<br />
<br />
=== Outcomes report ===<br />
This simple informational report displays all the outcomes used by the course, with the following information:<br />
<br />
*Outcome name<br />
*Overall average: If the outcome is used by more than one activity, this shows you the mean across all these activities in the current course<br />
*Site-wide: Yes or No: A site-wide outcome is automatically made available to all courses.<br />
*Activities: A list of links to the activities in the current course that use each outcome. One row per activity (table splits here)<br />
*Average: For each activity using the outcome, the average score is shown.<br />
*Number of grades: For each activity using the outcome, the number of grades is shown (non-graded participants are ignored)<br />
<br />
See [http://test.moodle.com/grade/report/outcomes/index.php?id=2 the test site] for a live demo of this report.<br />
<br />
=== Overview report ===<br />
Another basic report, showing a participant's course averages in each of the courses in which s/he has received grades.<br />
<br />
See [http://test.moodle.com/grade/report/overview/index.php the test site] for a live demo of this report.<br />
<br />
== Export plugins ==<br />
<br />
The API for these is extremely simple. Each export plugin should occupy a directory under /grade/export/xyz and needs to provide only an index.php file as a the primary interface. This file just accepts a 'courseid' parameter.<br />
<br />
== Import plugins ==<br />
<br />
Each import plugin should occupy a directory under /grade/import/xyz and needs to provide only an index.php file as a the primary interface. This file just accepts a 'courseid' parameter.<br />
<br />
The index.php will show an interface for further options and selections.<br />
<br />
Import plugin must validate data before starting the import operation, if some parts of import fail the user must be notified.<br />
<br />
Some sample import plugins are:<br />
<br />
===Import from CSV===<br />
<br />
Accepts an upload of (or URL to) a CSV file. Multiple options describe how to process the file, which columns to add etc. The imported grades always override current grades.<br />
<br />
===Import from XML===<br />
<br />
Accepts an upload of (or URL to) an XML file with this kind of format (from OU). <br />
<br />
<results batch="[someuniqueimportnumber]"><br />
<result><br />
<state>['new' or 'regrade']</state><br />
<assignment>[idnumber]</assignment><br />
<student>[studentid]</student><br />
<score>[score]</score><br />
</result><br />
<result><br />
<state>['new' or 'regrade']</state><br />
<assignment>[idnumber]</assignment><br />
<student>[studentid]</student><br />
<score>[score]</score><br />
</result><br />
[...]<br />
</results><br />
<br />
== Capabilities and Permissions ==<br />
<br />
* moodle/grade:view - view own grades or grades of other user if used in CONTEXT_USER<br />
<br />
* moodle/grade:viewall - view grades of all users<br />
<br />
* moodle/grade:viewhidden - see grades that are marked as hidden for the owner<br />
<br />
* moodle/grade:hide - be able to hide/unhide cells, items or categories<br />
<br />
* moodle/grade:lock - be able to lock cells, items or categories<br />
<br />
* moodle/grade:unlock - be able to unlock cells, items or categories<br />
<br />
* moodle/grade:manage - manage grade items and categories in gradebook (create, edit, lock, hide, delete, etc.)<br />
<br />
* moodle/grade:import - general import grades, requires separate permission for each plugin<br />
<br />
* moodle/grade:export - export grades, requires separate permission for each plugin<br />
<br />
* gradereport/grader:view - can view the grader report<br />
<br />
* gradeimport/csv:view - can view/use the csv import plugin<br />
<br />
* gradeexport/csv:view - can view/use the csv export plugin<br />
<br />
* moodle:site/accessallgroups<br />
<br />
== Development Tasks and Tracking ==<br />
<br />
For details of 1.9 development see [http://tracker.moodle.org/browse/MDL-9137 MDL-9137]<br />
<br />
For details of 2.0 development see [https://docs.moodle.org/en/Development:Gradebook_improvements Gradebook_imporovements] and [http://tracker.moodle.org/browse/MDL-19131 MDL-19131]<br />
<br />
==Updating module code==<br />
Module authors must implement new gradebook API and add upgrade code for migration of old grades into new gradebook. Fortunately the needed changes are not big.<br />
<br />
Steps:<br />
*add xxx_update_grades() function into mod/xxx/lib.php<br />
*add xxx_grade_item_update() function into mod/xxx/lib.php<br />
*patch xxx_update_instance(), xxx_add_instance() and xxx_delete_instance() to call xxx_grade_item_update()<br />
*patch all places of code that change grade values to call xxx_update_grades()<br />
*patch code that displays grades to students to use final grades from the gradebook<br />
<br />
There are many examples in official modules, assignment has the most advanced implementation.<br />
<br />
== Ideas for the future ==<br />
{{Moodle 2.0}}<br />
TODO: add new meta issue into tracker<br />
<br />
*option to aggregate including/excluding hidden grades - needs db changes<br />
*option to rollback all changes during import operation if anything fails<br />
*performance improvements<br />
*conditional activities<br />
*course completion criteria<br />
*better public API for modules<br />
*better API for gradebook plugins<br />
*better state tracking in export plugins<br />
*ajax reports<br />
*specialised reports<br />
*submission and marking date tracking db changes<br />
*calculation formula improvements<br />
*historical views<br />
*individual graph of grades (time vs %). Bar graph, lineal graph. Add (or not) the maximum posible; line of 0 (=minimum), 25, 50 (=median), 75 and 100 (=max) percentils of the group.<br />
*<br />
<br />
== See also ==<br />
<br />
* [http://moodle.org/mod/forum/discuss.php?d=69223&mode=3 Gradebook Development ideas] forum discussion<br />
* Using Moodle [http://moodle.org/mod/forum/discuss.php?d=51107 New gradebook for Moodle] forum discussion<br />
* [[Development:Gradebook Report Tutorial]]<br />
<br />
[[Category:Developer|Grades]]<br />
[[Category:Grades]]</div>Andyjdavishttps://docs.moodle.org/20/en/index.php?title=Development_talk:Bug_triage&diff=78937Development talk:Bug triage2010-12-08T06:56:18Z<p>Andyjdavis: /* More triage brainstorming */</p>
<hr />
<div>==Requesting input from other developers==<br />
<br />
Sometimes it's hard to know when somebody has been added as watcher in order to require input from him/her. That's because own watches aren't different at all from "request watches" from other developers.<br />
<br />
IMO it could be really interesting to have one new field, possibly only for developers and testers, in order to request input from other moodlers. That way, we could have one simple filter, call it, "Bugs I've been requested to input about". By taking a quick look to that list daily I think we could improve the decision process in a nice way.<br />
<br />
Commented with Martin and agreed about to suggest it here. Thanks! --[[User:Eloy Lafuente (stronk7)|Eloy Lafuente (stronk7)]] 10:51, 31 March 2008 (CDT)<br />
<br />
:Eloy, I like your idea, however I don't know a way of creating a field for developers and testers only. (I wish fields like QA assignee and difficulty could be removed from the create issue form to make the form shorter.) Perhaps we could implement your idea by reassigning the issue to someone when you want their input and adding a comment like 'Reassigning to Helen for her input on whether more documentation is needed. Please reassign back to me afterwards.' --[[User:Helen Foster|Helen Foster]] 13:02, 3 September 2009 (UTC)<br />
<br />
::Yes, temporal reassigning could be a solution, but main problem is that the original assignee can lost the track of the issue easily (if forgets to add him/her-self as watcher or so). Also, that won't solve the problem of searching for those bugs (based in one "free-content" string, any typo or change in the entered text will cause the issue to not appear in the list of "Requesting my opinion". Those are the reason about to have one specialised field for easier searching. About the fields... I haven't tested that... but... aren't the QA and difficulty fields only available (for input) to some groups within Jira? Do a simple Jira user have those fields available when creating new issues? I hope no. --[[User:Eloy Lafuente (stronk7)|Eloy Lafuente (stronk7)]] 13:58, 3 September 2009 (UTC)<br />
<br />
::Edited: Crap! I just created a new user in Jira and, when creating new issues, the QA and difficulty fields are available :-( --[[User:Eloy Lafuente (stronk7)|Eloy Lafuente (stronk7)]] 13:58, 3 September 2009 (UTC)<br />
<br />
::Edited 2: Seems to be an old JIRA limit: http://jira.atlassian.com/browse/JRA-4616 (hackable, see last comment, but I wouldn't recommend it). --[[User:Eloy Lafuente (stronk7)|Eloy Lafuente (stronk7)]] 14:13, 3 September 2009 (UTC)<br />
<br />
:::Yes, the only field which is not available to an ordinary Jira user is the assignee field. --[[User:Helen Foster|Helen Foster]] 14:09, 3 September 2009 (UTC)<br />
<br />
::::I'm not sure we need this. I think there is a risk of over-engineering the bug database when all you need are comment. If you want input from a particular person, add them as a watcher, then add a comment with the question you want them to answer. Sometimes we need extra fields like QA assignee, but this is not one of them, I think.--[[User:Tim Hunt|Tim Hunt]] 19:41, 13 September 2009 (UTC)<br />
<br />
==Sharing the responsibility of bug triaging==<br />
<br />
I've been rewording [[Development:Bug triage]] to hopefully make the two-step process a bit clearer. I was thinking that I could help with step 1, as could any developers new to Moodle. Senior developers could then help with step 2.<br />
<br />
Commenting promptly on new issues will act as an encouragement to bug reporters. Not having to check whether a bug can be reproduced should help senior developers triage bugs more efficiently.<br />
<br />
Any comments on this way of sharing the responsibility of bug triaging? --[[User:Helen Foster|Helen Foster]] 14:23, 3 September 2009 (UTC)<br />
<br />
==Life after triage==<br />
<br />
Bugs are removed from the triage list by giving them a fix version or closing them. What happens to all unresolved bugs then? How can we keep the list of triaged bugs as low as possible? Here are some suggestions from Eloy:<br />
<br />
* Encourage all Moodle HQ developers to identify and fix a minimum of 3 stable bugs per week. Perhaps send an email reminder.<br />
* 'Perhaps also we could introduce, one day per week, to have a quick review in the developer chat about some bugs needing decision. So, while we are triaging... we comment with some "keyword" and then can look for those or so.'<br />
<br />
--[[User:Helen Foster|Helen Foster]] 14:42, 3 September 2009 (UTC)<br />
<br />
== BUG: Bugs are not removed from the triage list ==<br />
<br />
"Bugs are removed from the triage list by giving them a fix version..." - does not seem to workBug_triage<br />
<br />
For example, MDL-20270 still appears at http://tracker.moodle.org/secure/IssueNavigator.jspa?mode=hide&requestId=10231 even I set a fix version to it<br />
<br />
--[[User:David Mudrak|David Mudrak]] 08:21, 14 September 2009 (UTC)<br />
<br />
:David, thanks for your observation. I've just edited the Recent unresolved bugs that need triage filter so that issues with fix versions are now omitted. I also checked that the fix version field doesn't appear in the create issue form for non-developers. Developers (i.e. users in the jira developers group) can of course create new issues with fix versions and so bypass the triage process. --[[User:Helen Foster|Helen Foster]] 13:05, 14 September 2009 (UTC)<br />
<br />
==More triage brainstorming==<br />
<br />
Ideas from Eloy:<br />
<br />
Use the new labels in the Tracker, to tag already triaged bugs with "triaged" or so, that will help looking both for non-triaged bugs and to see "how-many" we have triaged x unit of time (week, month... whatever). If you are in the middle of a triaging session, you add the label. If not, and it's one bug created and assigned in that moment, we don't use the label. That way, each week the triaging team will be able to say: this week xxx bugs triaged. Also, we can use "re-triage" in case somebody request to change triaging (though I don't think it's usual). Note triage can be, "trg" or whatever acronym we use, can be: p1 (phase1=triaging), others can use p2, p3.... so, at any moment it will be really easy to know in which situation one bug is.<br />
<br />
Consider a JIRA add-on for detecting duplicates (ideally, when the user introduces it) e.g. http://www.suggestimate.com/ (automated duplicates on creation for JIRA, free for open source projects)<br />
<br />
Have an automated system able to:<br />
#Get any nobody/moodle.com not-triaged bug.<br />
#Calculate the better assignee (from HQ) with some % of confidence in the calculation (based not only in component but in other things like number of bugs, number of bugs fixed in the same component)<br />
#If the % of confidence > than, say, 80%, automatically do the assignment.<br />
#Else, allow us to manually pick the best assignee.<br />
<br />
It is not triage, but moving from nobody/moodle.com to best assignee. For us it would be simply one page with one list and some checkboxes to validate the results of the automatic assignment.<br />
<br />
We need to decide what to set in the triaging process: only fix for or also always assignee (because that is another role "product backlog/master" in MD explanations), in other words specify clearly what has to be done in each phase of the issue:<br />
<br />
* triaging<br />
* backlog mashup<br />
* scrum/whatever they are going to use<br />
* development<br />
* test<br />
* development review<br />
* QA<br />
* land to codebase<br />
<br />
or we'll end mixing everything, with landing happening before QA, triaging after development... and all those sort of nasty things happening now.<br />
<br />
Another idea - error reporting:<br />
<br />
* Imagine Moodle shows one error/exception<br />
* Each time that happens, internally Moodle calculates one hash of the trace of the error and shows it. That hash is uniquely based in the information provided by the trace (those lines being showed with debugging enabled saying error in line xxx of yyyy and so on). Obviously we should take out some varying information from the hash (like line numbers or complete paths).<br />
* In the tracker we allow those hashes to be introduced, so later they can be used both for finding already fixed problems and duplicates.<br />
<br />
More yet, sites allowed to do so could be publishing those errors straight to Moodle Tracker, getting 1-vote for each site that has reported the problem, I think that can help a lot with error-based issues, and also, from sites allowed to do so... we would be getting INSTANT reports about real errors.<br />
<br />
Idea from Andrew:<br />
<br />
Either as a one off manual process or as an ongoing automatic process we could auto-close old issues:<br />
* Issues that have been resolved for 12 months.<br />
* Issues that are open but which have been inactive for 2 years and have less than 3 votes.<br />
<br />
Looking to get issues closed that are either dealt with or are likely so old that they are irrelevant or are actually duplicates of issues that have been resolved.<br />
<br />
==See also==<br />
<br />
*https://wiki.foresightlinux.org/display/teams/HowTo+Triage+Bugs+in+JIRA<br />
*[http://moodle.org/mod/cvsadmin/view.php?conversationid=3309#c144293 Developer conversation 28/09/09 about determining whether bugs have been triaged or not]</div>Andyjdavishttps://docs.moodle.org/20/en/index.php?title=Development:Gradebook_improvements&diff=78418Development:Gradebook improvements2010-11-29T06:08:41Z<p>Andyjdavis: /* Stage 2 */</p>
<hr />
<div>{{Work in progress}}<br />
{{Moodle 2.0}}Improving the usability of the Moodle gradebook is one of the main targets for Moodle 2.0.<br />
<br />
This evolving page summarises a number of proposed changes, derived from community suggestions in the [http://moodle.org/mod/forum/view.php?id=2122 Gradebook forum] and in the [http://tracker.moodle.org/secure/Dashboard.jspa tracker], with special attention given to [http://tracker.moodle.org/browse/MDL/component/10062?selected=com.atlassian.jira.plugin.system.project:component-popularissues-panel the issues with the most votes].<br />
<br />
We would really like your feedback on:<br />
<br />
# The changes already proposed here<br />
# Any issues that you feel are not yet addressed<br />
<br />
We would also like your contributions to [[Gradebook uses]].<br />
<br />
Please join the discussions and post your suggestions in the [http://moodle.org/mod/forum/view.php?id=2122 Gradebook forum].<br />
<br />
<br />
==Stage 1==<br />
[[Image:Edit categories and items.png|thumb|Edit categories and items advanced settings]]<br />
''May 2009 progress update: Stage 1 has now been completed, with improvements implemented in Moodle 1.9.5 and 2.0. See [[Gradebook improvements in Moodle 1.9.5]] for details.''<br />
<br />
===Easier editing of categories and items===<br />
<br />
* MDL-16913 New "Edit categories and items" page, with hide/show advanced settings, moving of multiple items between categories and quick editing of multiple settings<br />
* MDL-17829 Combine category grade item and category edit forms<br />
<br />
===Report improvements===<br />
[[Image:Simple_grader_report_scroll.jpg|thumb|Simple grader report from LSU]]<br />
* MDL-18228 Add horizontal scrollbar in grader report to scroll grades while students stay fixed (as used in the LSU [[grade/report/simple grader/index|simple grader report]])<br />
* MDL-17991 New visual organization for gradebook user report (including category nesting, ranges)<br />
[[Image:User report.png|thumb|User report]]<br />
===Better gradebook navigation===<br />
<br />
* MDL-18004 Implement tabs navigation<br />
* MDL-12631 Grader report breadcrumbs are too long<br />
<br />
===Simplifying the gradebook===<br />
<br />
* MDL-18321 Change gradereport/overview:view default setting to 'Not set' for the role of teacher and non-editing teacher in new installs<br />
* [[Simplifying the gradebook by changing permissions]] - documentation on how to provide a simplified gradebook for teachers by changing certain permissions<br />
* MDL-12380 Add an admin setting for selecting which aggregation types are available<br />
* MDL-18523 Only display the 'Synchronise legacy grades' button when necessary<br />
<br />
===Groups access===<br />
<br />
* MDL-18119 Restrict teachers to their own groups when accessing User Reports<br />
* MDL-15617 Showing all groups in gradebook when user restricted to one<br />
<br />
===Further bug fixes and improvements===<br />
<br />
* MDL-14961 Adding a help button next to the "Synchronise legacy grades"<br />
* MDL-13417 Outcomes report is available even when outcomes are disabled<br />
* MDL-12380 Allow grades over 100%<br />
* MDL-14831, MDL-15033 and MDL-16363 Issues relating to the "Sum of grades" aggregation type<br />
<br />
==Stage 2==<br />
''Nov 2010 progress update: Stage 2 has now been completed, with improvements implemented in 2.0. Items that were not completed have been bumped to stage 3 (Moodle 2.1)''<br />
<br />
For more details about these items see MDL-19131 Gradebook 2.0 - META.<br />
<br />
===Centralisation of grade item settings in gradebook===<br />
* MDL-19133 Module forms remain the same, but they draw their "Grade" section from gradebook code<br />
<br />
===Gradebook help===<br />
<br />
* Review current [[Gradebook help files]] and check for consistency<br />
* MDL-13960 Make full use of title attributes in the gradebook<br />
<br />
==Stage 3==<br />
For more details about these items see MDL-25423 Gradebook 2.1 - META. <br />
<br />
===Simplifying the gradebook further===<br />
<br />
* MDL-18049 Investigate ways of reducing the number of settings in the gradebook. Currently only grade category settings can be forced and hidden by an admin. See [[Development:Gradebook settings review]].<br />
* MDL-20250 Add admin settings for disabling gradebook features such as multiplicator, offset, calculations<br />
<br />
===Outcomes===<br />
<br />
* Review outcomes and how they are implemented in the gradebook. MDL-10685 is part of this.<br />
* MDL-16103 Have an icon for outcomes on the edit categories and items page<br />
<br />
===Centralisation of grade item settings in gradebook===<br />
* Hide, Lock, Maximum Grade and other grade item settings in module forms are saved in the gradebook tables, not in module tables<br />
<br />
===Scales Refactoring===<br />
* MDL-17258 Custom non-numeric scales to have assigned numeric value in gradebook<br />
<br />
==Further changes under consideration==<br />
[[Image:Continuous grade distribution.png|thumb|Animated grade statistics report]]<br />
[[Image:Simple_grader_quick_edit_student.png|thumb|Student grades quick edit from LSU]]<br />
* MDL-15050 Grades entered in 1.9 gradebook should show in student activity report<br />
* MDL-13501 [[Student projects/Animated grade statistics report|Animated grade statistics report]] (GSoC project by Daniel Servos)<br />
* MDL-12203 Bulk message direct from the gradebook<br />
* MDL-18229 Add grade item and student grades quick edit feature to the grader report (with thanks to developers at the LSU for their [[grade/report/simple grader/quick edit|quick edit screens]])<br />
* MDL-18163 Provide summary statistics in the gradebook<br />
* MDL-16801 Create a grade history GUI<br />
* MDL-25424 Provide a reason why a category/course total is not being displayed<br />
<br />
==See also==<br />
*[[Gradebook uses]]<br />
*[[Gradebook improvements in Moodle 1.9.5]]<br />
*[[Development talk:Gradebook improvements]]<br />
*[[Development:Gradebook settings review]]<br />
* MDL-18083 META: Gradebook improvements - Stage 1<br />
* MDL-19131 Gradebook 2.0 - META<br />
* MDL-20249 Gradebook 1.9.6 - META<br />
*[[Development:Grades]] for archive specification<br />
<br />
[[Category:Grades]]<br />
[[Category:Developer]]</div>Andyjdavishttps://docs.moodle.org/20/en/index.php?title=Development:Gradebook_improvements&diff=78417Development:Gradebook improvements2010-11-29T06:07:48Z<p>Andyjdavis: /* Hidden activities */</p>
<hr />
<div>{{Work in progress}}<br />
{{Moodle 2.0}}Improving the usability of the Moodle gradebook is one of the main targets for Moodle 2.0.<br />
<br />
This evolving page summarises a number of proposed changes, derived from community suggestions in the [http://moodle.org/mod/forum/view.php?id=2122 Gradebook forum] and in the [http://tracker.moodle.org/secure/Dashboard.jspa tracker], with special attention given to [http://tracker.moodle.org/browse/MDL/component/10062?selected=com.atlassian.jira.plugin.system.project:component-popularissues-panel the issues with the most votes].<br />
<br />
We would really like your feedback on:<br />
<br />
# The changes already proposed here<br />
# Any issues that you feel are not yet addressed<br />
<br />
We would also like your contributions to [[Gradebook uses]].<br />
<br />
Please join the discussions and post your suggestions in the [http://moodle.org/mod/forum/view.php?id=2122 Gradebook forum].<br />
<br />
<br />
==Stage 1==<br />
[[Image:Edit categories and items.png|thumb|Edit categories and items advanced settings]]<br />
''May 2009 progress update: Stage 1 has now been completed, with improvements implemented in Moodle 1.9.5 and 2.0. See [[Gradebook improvements in Moodle 1.9.5]] for details.''<br />
<br />
===Easier editing of categories and items===<br />
<br />
* MDL-16913 New "Edit categories and items" page, with hide/show advanced settings, moving of multiple items between categories and quick editing of multiple settings<br />
* MDL-17829 Combine category grade item and category edit forms<br />
<br />
===Report improvements===<br />
[[Image:Simple_grader_report_scroll.jpg|thumb|Simple grader report from LSU]]<br />
* MDL-18228 Add horizontal scrollbar in grader report to scroll grades while students stay fixed (as used in the LSU [[grade/report/simple grader/index|simple grader report]])<br />
* MDL-17991 New visual organization for gradebook user report (including category nesting, ranges)<br />
[[Image:User report.png|thumb|User report]]<br />
===Better gradebook navigation===<br />
<br />
* MDL-18004 Implement tabs navigation<br />
* MDL-12631 Grader report breadcrumbs are too long<br />
<br />
===Simplifying the gradebook===<br />
<br />
* MDL-18321 Change gradereport/overview:view default setting to 'Not set' for the role of teacher and non-editing teacher in new installs<br />
* [[Simplifying the gradebook by changing permissions]] - documentation on how to provide a simplified gradebook for teachers by changing certain permissions<br />
* MDL-12380 Add an admin setting for selecting which aggregation types are available<br />
* MDL-18523 Only display the 'Synchronise legacy grades' button when necessary<br />
<br />
===Groups access===<br />
<br />
* MDL-18119 Restrict teachers to their own groups when accessing User Reports<br />
* MDL-15617 Showing all groups in gradebook when user restricted to one<br />
<br />
===Further bug fixes and improvements===<br />
<br />
* MDL-14961 Adding a help button next to the "Synchronise legacy grades"<br />
* MDL-13417 Outcomes report is available even when outcomes are disabled<br />
* MDL-12380 Allow grades over 100%<br />
* MDL-14831, MDL-15033 and MDL-16363 Issues relating to the "Sum of grades" aggregation type<br />
<br />
==Stage 2==<br />
''Nov 2010 progress update: Stage 2 has now been completed, with improvements implemented in 2.0. Items that were not completed have been bumped to stage 3 (Moodle 2.1)''<br />
<br />
For more details about these items see MDL-19131 Gradebook 2.0 - META.<br />
<br />
===Begin migrating grading code into common code===<br />
* MDL-19133<br />
<br />
===Gradebook help===<br />
<br />
* Review current [[Gradebook help files]] and check for consistency<br />
* MDL-13960 Make full use of title attributes in the gradebook<br />
<br />
===Centralisation of grade item settings in gradebook===<br />
* Module forms remain the same, but they draw their "Grade" section from gradebook code<br />
<br />
==Stage 3==<br />
For more details about these items see MDL-25423 Gradebook 2.1 - META. <br />
<br />
===Simplifying the gradebook further===<br />
<br />
* MDL-18049 Investigate ways of reducing the number of settings in the gradebook. Currently only grade category settings can be forced and hidden by an admin. See [[Development:Gradebook settings review]].<br />
* MDL-20250 Add admin settings for disabling gradebook features such as multiplicator, offset, calculations<br />
<br />
===Outcomes===<br />
<br />
* Review outcomes and how they are implemented in the gradebook. MDL-10685 is part of this.<br />
* MDL-16103 Have an icon for outcomes on the edit categories and items page<br />
<br />
===Centralisation of grade item settings in gradebook===<br />
* Hide, Lock, Maximum Grade and other grade item settings in module forms are saved in the gradebook tables, not in module tables<br />
<br />
===Scales Refactoring===<br />
* MDL-17258 Custom non-numeric scales to have assigned numeric value in gradebook<br />
<br />
==Further changes under consideration==<br />
[[Image:Continuous grade distribution.png|thumb|Animated grade statistics report]]<br />
[[Image:Simple_grader_quick_edit_student.png|thumb|Student grades quick edit from LSU]]<br />
* MDL-15050 Grades entered in 1.9 gradebook should show in student activity report<br />
* MDL-13501 [[Student projects/Animated grade statistics report|Animated grade statistics report]] (GSoC project by Daniel Servos)<br />
* MDL-12203 Bulk message direct from the gradebook<br />
* MDL-18229 Add grade item and student grades quick edit feature to the grader report (with thanks to developers at the LSU for their [[grade/report/simple grader/quick edit|quick edit screens]])<br />
* MDL-18163 Provide summary statistics in the gradebook<br />
* MDL-16801 Create a grade history GUI<br />
* MDL-25424 Provide a reason why a category/course total is not being displayed<br />
<br />
==See also==<br />
*[[Gradebook uses]]<br />
*[[Gradebook improvements in Moodle 1.9.5]]<br />
*[[Development talk:Gradebook improvements]]<br />
*[[Development:Gradebook settings review]]<br />
* MDL-18083 META: Gradebook improvements - Stage 1<br />
* MDL-19131 Gradebook 2.0 - META<br />
* MDL-20249 Gradebook 1.9.6 - META<br />
*[[Development:Grades]] for archive specification<br />
<br />
[[Category:Grades]]<br />
[[Category:Developer]]</div>Andyjdavishttps://docs.moodle.org/20/en/index.php?title=Development:Gradebook_improvements&diff=78317Development:Gradebook improvements2010-11-26T09:06:43Z<p>Andyjdavis: /* Outcomes */</p>
<hr />
<div>{{Work in progress}}<br />
{{Moodle 2.0}}Improving the usability of the Moodle gradebook is one of the main targets for Moodle 2.0.<br />
<br />
This evolving page summarises a number of proposed changes, derived from community suggestions in the [http://moodle.org/mod/forum/view.php?id=2122 Gradebook forum] and in the [http://tracker.moodle.org/secure/Dashboard.jspa tracker], with special attention given to [http://tracker.moodle.org/browse/MDL/component/10062?selected=com.atlassian.jira.plugin.system.project:component-popularissues-panel the issues with the most votes].<br />
<br />
We would really like your feedback on:<br />
<br />
# The changes already proposed here<br />
# Any issues that you feel are not yet addressed<br />
<br />
We would also like your contributions to [[Gradebook uses]].<br />
<br />
Please join the discussions and post your suggestions in the [http://moodle.org/mod/forum/view.php?id=2122 Gradebook forum].<br />
<br />
<br />
==Stage 1==<br />
[[Image:Edit categories and items.png|thumb|Edit categories and items advanced settings]]<br />
''May 2009 progress update: Stage 1 has now been completed, with improvements implemented in Moodle 1.9.5 and 2.0. See [[Gradebook improvements in Moodle 1.9.5]] for details.''<br />
<br />
===Easier editing of categories and items===<br />
<br />
* MDL-16913 New "Edit categories and items" page, with hide/show advanced settings, moving of multiple items between categories and quick editing of multiple settings<br />
* MDL-17829 Combine category grade item and category edit forms<br />
<br />
===Report improvements===<br />
[[Image:Simple_grader_report_scroll.jpg|thumb|Simple grader report from LSU]]<br />
* MDL-18228 Add horizontal scrollbar in grader report to scroll grades while students stay fixed (as used in the LSU [[grade/report/simple grader/index|simple grader report]])<br />
* MDL-17991 New visual organization for gradebook user report (including category nesting, ranges)<br />
[[Image:User report.png|thumb|User report]]<br />
===Better gradebook navigation===<br />
<br />
* MDL-18004 Implement tabs navigation<br />
* MDL-12631 Grader report breadcrumbs are too long<br />
<br />
===Simplifying the gradebook===<br />
<br />
* MDL-18321 Change gradereport/overview:view default setting to 'Not set' for the role of teacher and non-editing teacher in new installs<br />
* [[Simplifying the gradebook by changing permissions]] - documentation on how to provide a simplified gradebook for teachers by changing certain permissions<br />
* MDL-12380 Add an admin setting for selecting which aggregation types are available<br />
* MDL-18523 Only display the 'Synchronise legacy grades' button when necessary<br />
<br />
===Groups access===<br />
<br />
* MDL-18119 Restrict teachers to their own groups when accessing User Reports<br />
* MDL-15617 Showing all groups in gradebook when user restricted to one<br />
<br />
===Further bug fixes and improvements===<br />
<br />
* MDL-14961 Adding a help button next to the "Synchronise legacy grades"<br />
* MDL-13417 Outcomes report is available even when outcomes are disabled<br />
* MDL-12380 Allow grades over 100%<br />
* MDL-14831, MDL-15033 and MDL-16363 Issues relating to the "Sum of grades" aggregation type<br />
<br />
==Stage 2==<br />
''Nov 2010 progress update: Stage 2 has now been completed, with improvements implemented in 2.0. Items that were not completed have been bumped to stage 3 (Moodle 2.1)''<br />
<br />
For more details about these items see MDL-19131 Gradebook 2.0 - META.<br />
<br />
===Hidden activities===<br />
* MDL-19133<br />
<br />
===Gradebook help===<br />
<br />
* Review current [[Gradebook help files]] and check for consistency<br />
* MDL-13960 Make full use of title attributes in the gradebook<br />
<br />
===Centralisation of grade item settings in gradebook===<br />
* Module forms remain the same, but they draw their "Grade" section from gradebook code<br />
<br />
==Stage 3==<br />
For more details about these items see MDL-25423 Gradebook 2.1 - META. <br />
<br />
===Simplifying the gradebook further===<br />
<br />
* MDL-18049 Investigate ways of reducing the number of settings in the gradebook. Currently only grade category settings can be forced and hidden by an admin. See [[Development:Gradebook settings review]].<br />
* MDL-20250 Add admin settings for disabling gradebook features such as multiplicator, offset, calculations<br />
<br />
===Outcomes===<br />
<br />
* Review outcomes and how they are implemented in the gradebook. MDL-10685 is part of this.<br />
* MDL-16103 Have an icon for outcomes on the edit categories and items page<br />
<br />
===Centralisation of grade item settings in gradebook===<br />
* Hide, Lock, Maximum Grade and other grade item settings in module forms are saved in the gradebook tables, not in module tables<br />
<br />
===Scales Refactoring===<br />
* MDL-17258 Custom non-numeric scales to have assigned numeric value in gradebook<br />
<br />
==Further changes under consideration==<br />
[[Image:Continuous grade distribution.png|thumb|Animated grade statistics report]]<br />
[[Image:Simple_grader_quick_edit_student.png|thumb|Student grades quick edit from LSU]]<br />
* MDL-15050 Grades entered in 1.9 gradebook should show in student activity report<br />
* MDL-13501 [[Student projects/Animated grade statistics report|Animated grade statistics report]] (GSoC project by Daniel Servos)<br />
* MDL-12203 Bulk message direct from the gradebook<br />
* MDL-18229 Add grade item and student grades quick edit feature to the grader report (with thanks to developers at the LSU for their [[grade/report/simple grader/quick edit|quick edit screens]])<br />
* MDL-18163 Provide summary statistics in the gradebook<br />
* MDL-16801 Create a grade history GUI<br />
* MDL-25424 Provide a reason why a category/course total is not being displayed<br />
<br />
==See also==<br />
*[[Gradebook uses]]<br />
*[[Gradebook improvements in Moodle 1.9.5]]<br />
*[[Development talk:Gradebook improvements]]<br />
*[[Development:Gradebook settings review]]<br />
* MDL-18083 META: Gradebook improvements - Stage 1<br />
* MDL-19131 Gradebook 2.0 - META<br />
* MDL-20249 Gradebook 1.9.6 - META<br />
*[[Development:Grades]] for archive specification<br />
<br />
[[Category:Grades]]<br />
[[Category:Developer]]</div>Andyjdavishttps://docs.moodle.org/20/en/index.php?title=Development:Gradebook_improvements&diff=78315Development:Gradebook improvements2010-11-26T08:59:50Z<p>Andyjdavis: /* Further changes under consideration */</p>
<hr />
<div>{{Work in progress}}<br />
{{Moodle 2.0}}Improving the usability of the Moodle gradebook is one of the main targets for Moodle 2.0.<br />
<br />
This evolving page summarises a number of proposed changes, derived from community suggestions in the [http://moodle.org/mod/forum/view.php?id=2122 Gradebook forum] and in the [http://tracker.moodle.org/secure/Dashboard.jspa tracker], with special attention given to [http://tracker.moodle.org/browse/MDL/component/10062?selected=com.atlassian.jira.plugin.system.project:component-popularissues-panel the issues with the most votes].<br />
<br />
We would really like your feedback on:<br />
<br />
# The changes already proposed here<br />
# Any issues that you feel are not yet addressed<br />
<br />
We would also like your contributions to [[Gradebook uses]].<br />
<br />
Please join the discussions and post your suggestions in the [http://moodle.org/mod/forum/view.php?id=2122 Gradebook forum].<br />
<br />
<br />
==Stage 1==<br />
[[Image:Edit categories and items.png|thumb|Edit categories and items advanced settings]]<br />
''May 2009 progress update: Stage 1 has now been completed, with improvements implemented in Moodle 1.9.5 and 2.0. See [[Gradebook improvements in Moodle 1.9.5]] for details.''<br />
<br />
===Easier editing of categories and items===<br />
<br />
* MDL-16913 New "Edit categories and items" page, with hide/show advanced settings, moving of multiple items between categories and quick editing of multiple settings<br />
* MDL-17829 Combine category grade item and category edit forms<br />
<br />
===Report improvements===<br />
[[Image:Simple_grader_report_scroll.jpg|thumb|Simple grader report from LSU]]<br />
* MDL-18228 Add horizontal scrollbar in grader report to scroll grades while students stay fixed (as used in the LSU [[grade/report/simple grader/index|simple grader report]])<br />
* MDL-17991 New visual organization for gradebook user report (including category nesting, ranges)<br />
[[Image:User report.png|thumb|User report]]<br />
===Better gradebook navigation===<br />
<br />
* MDL-18004 Implement tabs navigation<br />
* MDL-12631 Grader report breadcrumbs are too long<br />
<br />
===Simplifying the gradebook===<br />
<br />
* MDL-18321 Change gradereport/overview:view default setting to 'Not set' for the role of teacher and non-editing teacher in new installs<br />
* [[Simplifying the gradebook by changing permissions]] - documentation on how to provide a simplified gradebook for teachers by changing certain permissions<br />
* MDL-12380 Add an admin setting for selecting which aggregation types are available<br />
* MDL-18523 Only display the 'Synchronise legacy grades' button when necessary<br />
<br />
===Groups access===<br />
<br />
* MDL-18119 Restrict teachers to their own groups when accessing User Reports<br />
* MDL-15617 Showing all groups in gradebook when user restricted to one<br />
<br />
===Further bug fixes and improvements===<br />
<br />
* MDL-14961 Adding a help button next to the "Synchronise legacy grades"<br />
* MDL-13417 Outcomes report is available even when outcomes are disabled<br />
* MDL-12380 Allow grades over 100%<br />
* MDL-14831, MDL-15033 and MDL-16363 Issues relating to the "Sum of grades" aggregation type<br />
<br />
==Stage 2==<br />
''Nov 2010 progress update: Stage 2 has now been completed, with improvements implemented in 2.0. Items that were not completed have been bumped to stage 3 (Moodle 2.1)''<br />
<br />
For more details about these items see MDL-19131 Gradebook 2.0 - META.<br />
<br />
===Hidden activities===<br />
* MDL-19133<br />
<br />
===Gradebook help===<br />
<br />
* Review current [[Gradebook help files]] and check for consistency<br />
* MDL-13960 Make full use of title attributes in the gradebook<br />
<br />
===Centralisation of grade item settings in gradebook===<br />
* Module forms remain the same, but they draw their "Grade" section from gradebook code<br />
<br />
==Stage 3==<br />
For more details about these items see MDL-25423 Gradebook 2.1 - META. <br />
<br />
===Simplifying the gradebook further===<br />
<br />
* MDL-18049 Investigate ways of reducing the number of settings in the gradebook. Currently only grade category settings can be forced and hidden by an admin. See [[Development:Gradebook settings review]].<br />
* MDL-20250 Add admin settings for disabling gradebook features such as multiplicator, offset, calculations<br />
<br />
===Outcomes===<br />
<br />
* Review outcomes and how they are implemented in the gradebook<br />
* MDL-16103 Have an icon for outcomes on the edit categories and items page<br />
<br />
===Centralisation of grade item settings in gradebook===<br />
* Hide, Lock, Maximum Grade and other grade item settings in module forms are saved in the gradebook tables, not in module tables<br />
<br />
===Scales Refactoring===<br />
* MDL-17258 Custom non-numeric scales to have assigned numeric value in gradebook<br />
<br />
==Further changes under consideration==<br />
[[Image:Continuous grade distribution.png|thumb|Animated grade statistics report]]<br />
[[Image:Simple_grader_quick_edit_student.png|thumb|Student grades quick edit from LSU]]<br />
* MDL-15050 Grades entered in 1.9 gradebook should show in student activity report<br />
* MDL-13501 [[Student projects/Animated grade statistics report|Animated grade statistics report]] (GSoC project by Daniel Servos)<br />
* MDL-12203 Bulk message direct from the gradebook<br />
* MDL-18229 Add grade item and student grades quick edit feature to the grader report (with thanks to developers at the LSU for their [[grade/report/simple grader/quick edit|quick edit screens]])<br />
* MDL-18163 Provide summary statistics in the gradebook<br />
* MDL-16801 Create a grade history GUI<br />
* MDL-25424 Provide a reason why a category/course total is not being displayed<br />
<br />
==See also==<br />
*[[Gradebook uses]]<br />
*[[Gradebook improvements in Moodle 1.9.5]]<br />
*[[Development talk:Gradebook improvements]]<br />
*[[Development:Gradebook settings review]]<br />
* MDL-18083 META: Gradebook improvements - Stage 1<br />
* MDL-19131 Gradebook 2.0 - META<br />
* MDL-20249 Gradebook 1.9.6 - META<br />
*[[Development:Grades]] for archive specification<br />
<br />
[[Category:Grades]]<br />
[[Category:Developer]]</div>Andyjdavishttps://docs.moodle.org/20/en/index.php?title=Development:Gradebook_improvements&diff=78310Development:Gradebook improvements2010-11-26T07:48:27Z<p>Andyjdavis: /* Further changes under consideration */</p>
<hr />
<div>{{Work in progress}}<br />
{{Moodle 2.0}}Improving the usability of the Moodle gradebook is one of the main targets for Moodle 2.0.<br />
<br />
This evolving page summarises a number of proposed changes, derived from community suggestions in the [http://moodle.org/mod/forum/view.php?id=2122 Gradebook forum] and in the [http://tracker.moodle.org/secure/Dashboard.jspa tracker], with special attention given to [http://tracker.moodle.org/browse/MDL/component/10062?selected=com.atlassian.jira.plugin.system.project:component-popularissues-panel the issues with the most votes].<br />
<br />
We would really like your feedback on:<br />
<br />
# The changes already proposed here<br />
# Any issues that you feel are not yet addressed<br />
<br />
We would also like your contributions to [[Gradebook uses]].<br />
<br />
Please join the discussions and post your suggestions in the [http://moodle.org/mod/forum/view.php?id=2122 Gradebook forum].<br />
<br />
<br />
==Stage 1==<br />
[[Image:Edit categories and items.png|thumb|Edit categories and items advanced settings]]<br />
''May 2009 progress update: Stage 1 has now been completed, with improvements implemented in Moodle 1.9.5 and 2.0. See [[Gradebook improvements in Moodle 1.9.5]] for details.''<br />
<br />
===Easier editing of categories and items===<br />
<br />
* MDL-16913 New "Edit categories and items" page, with hide/show advanced settings, moving of multiple items between categories and quick editing of multiple settings<br />
* MDL-17829 Combine category grade item and category edit forms<br />
<br />
===Report improvements===<br />
[[Image:Simple_grader_report_scroll.jpg|thumb|Simple grader report from LSU]]<br />
* MDL-18228 Add horizontal scrollbar in grader report to scroll grades while students stay fixed (as used in the LSU [[grade/report/simple grader/index|simple grader report]])<br />
* MDL-17991 New visual organization for gradebook user report (including category nesting, ranges)<br />
[[Image:User report.png|thumb|User report]]<br />
===Better gradebook navigation===<br />
<br />
* MDL-18004 Implement tabs navigation<br />
* MDL-12631 Grader report breadcrumbs are too long<br />
<br />
===Simplifying the gradebook===<br />
<br />
* MDL-18321 Change gradereport/overview:view default setting to 'Not set' for the role of teacher and non-editing teacher in new installs<br />
* [[Simplifying the gradebook by changing permissions]] - documentation on how to provide a simplified gradebook for teachers by changing certain permissions<br />
* MDL-12380 Add an admin setting for selecting which aggregation types are available<br />
* MDL-18523 Only display the 'Synchronise legacy grades' button when necessary<br />
<br />
===Groups access===<br />
<br />
* MDL-18119 Restrict teachers to their own groups when accessing User Reports<br />
* MDL-15617 Showing all groups in gradebook when user restricted to one<br />
<br />
===Further bug fixes and improvements===<br />
<br />
* MDL-14961 Adding a help button next to the "Synchronise legacy grades"<br />
* MDL-13417 Outcomes report is available even when outcomes are disabled<br />
* MDL-12380 Allow grades over 100%<br />
* MDL-14831, MDL-15033 and MDL-16363 Issues relating to the "Sum of grades" aggregation type<br />
<br />
==Stage 2==<br />
''Nov 2010 progress update: Stage 2 has now been completed, with improvements implemented in 2.0. Items that were not completed have been bumped to stage 3 (Moodle 2.1)''<br />
<br />
For more details about these items see MDL-19131 Gradebook 2.0 - META.<br />
<br />
===Hidden activities===<br />
* MDL-19133<br />
<br />
===Gradebook help===<br />
<br />
* Review current [[Gradebook help files]] and check for consistency<br />
* MDL-13960 Make full use of title attributes in the gradebook<br />
<br />
===Centralisation of grade item settings in gradebook===<br />
* Module forms remain the same, but they draw their "Grade" section from gradebook code<br />
<br />
==Stage 3==<br />
For more details about these items see MDL-25423 Gradebook 2.1 - META. <br />
<br />
===Simplifying the gradebook further===<br />
<br />
* MDL-18049 Investigate ways of reducing the number of settings in the gradebook. Currently only grade category settings can be forced and hidden by an admin. See [[Development:Gradebook settings review]].<br />
* MDL-20250 Add admin settings for disabling gradebook features such as multiplicator, offset, calculations<br />
<br />
===Outcomes===<br />
<br />
* Review outcomes and how they are implemented in the gradebook<br />
* MDL-16103 Have an icon for outcomes on the edit categories and items page<br />
<br />
===Centralisation of grade item settings in gradebook===<br />
* Hide, Lock, Maximum Grade and other grade item settings in module forms are saved in the gradebook tables, not in module tables<br />
<br />
===Scales Refactoring===<br />
* MDL-17258 Custom non-numeric scales to have assigned numeric value in gradebook<br />
<br />
==Further changes under consideration==<br />
[[Image:Continuous grade distribution.png|thumb|Animated grade statistics report]]<br />
[[Image:Simple_grader_quick_edit_student.png|thumb|Student grades quick edit from LSU]]<br />
* MDL-15050 Grades entered in 1.9 gradebook should show in student activity report<br />
* MDL-13501 [[Student projects/Animated grade statistics report|Animated grade statistics report]] (GSoC project by Daniel Servos)<br />
* MDL-12203 Bulk message direct from the gradebook<br />
* MDL-18229 Add grade item and student grades quick edit feature to the grader report (with thanks to developers at the LSU for their [[grade/report/simple grader/quick edit|quick edit screens]])<br />
* MDL-18163 Provide summary statistics in the gradebook<br />
* MDL-16801 Create a grade history GUI<br />
<br />
==See also==<br />
*[[Gradebook uses]]<br />
*[[Gradebook improvements in Moodle 1.9.5]]<br />
*[[Development talk:Gradebook improvements]]<br />
*[[Development:Gradebook settings review]]<br />
* MDL-18083 META: Gradebook improvements - Stage 1<br />
* MDL-19131 Gradebook 2.0 - META<br />
* MDL-20249 Gradebook 1.9.6 - META<br />
*[[Development:Grades]] for archive specification<br />
<br />
[[Category:Grades]]<br />
[[Category:Developer]]</div>Andyjdavishttps://docs.moodle.org/20/en/index.php?title=Development:Gradebook_improvements&diff=78309Development:Gradebook improvements2010-11-26T07:46:02Z<p>Andyjdavis: /* Stage 3 */</p>
<hr />
<div>{{Work in progress}}<br />
{{Moodle 2.0}}Improving the usability of the Moodle gradebook is one of the main targets for Moodle 2.0.<br />
<br />
This evolving page summarises a number of proposed changes, derived from community suggestions in the [http://moodle.org/mod/forum/view.php?id=2122 Gradebook forum] and in the [http://tracker.moodle.org/secure/Dashboard.jspa tracker], with special attention given to [http://tracker.moodle.org/browse/MDL/component/10062?selected=com.atlassian.jira.plugin.system.project:component-popularissues-panel the issues with the most votes].<br />
<br />
We would really like your feedback on:<br />
<br />
# The changes already proposed here<br />
# Any issues that you feel are not yet addressed<br />
<br />
We would also like your contributions to [[Gradebook uses]].<br />
<br />
Please join the discussions and post your suggestions in the [http://moodle.org/mod/forum/view.php?id=2122 Gradebook forum].<br />
<br />
<br />
==Stage 1==<br />
[[Image:Edit categories and items.png|thumb|Edit categories and items advanced settings]]<br />
''May 2009 progress update: Stage 1 has now been completed, with improvements implemented in Moodle 1.9.5 and 2.0. See [[Gradebook improvements in Moodle 1.9.5]] for details.''<br />
<br />
===Easier editing of categories and items===<br />
<br />
* MDL-16913 New "Edit categories and items" page, with hide/show advanced settings, moving of multiple items between categories and quick editing of multiple settings<br />
* MDL-17829 Combine category grade item and category edit forms<br />
<br />
===Report improvements===<br />
[[Image:Simple_grader_report_scroll.jpg|thumb|Simple grader report from LSU]]<br />
* MDL-18228 Add horizontal scrollbar in grader report to scroll grades while students stay fixed (as used in the LSU [[grade/report/simple grader/index|simple grader report]])<br />
* MDL-17991 New visual organization for gradebook user report (including category nesting, ranges)<br />
[[Image:User report.png|thumb|User report]]<br />
===Better gradebook navigation===<br />
<br />
* MDL-18004 Implement tabs navigation<br />
* MDL-12631 Grader report breadcrumbs are too long<br />
<br />
===Simplifying the gradebook===<br />
<br />
* MDL-18321 Change gradereport/overview:view default setting to 'Not set' for the role of teacher and non-editing teacher in new installs<br />
* [[Simplifying the gradebook by changing permissions]] - documentation on how to provide a simplified gradebook for teachers by changing certain permissions<br />
* MDL-12380 Add an admin setting for selecting which aggregation types are available<br />
* MDL-18523 Only display the 'Synchronise legacy grades' button when necessary<br />
<br />
===Groups access===<br />
<br />
* MDL-18119 Restrict teachers to their own groups when accessing User Reports<br />
* MDL-15617 Showing all groups in gradebook when user restricted to one<br />
<br />
===Further bug fixes and improvements===<br />
<br />
* MDL-14961 Adding a help button next to the "Synchronise legacy grades"<br />
* MDL-13417 Outcomes report is available even when outcomes are disabled<br />
* MDL-12380 Allow grades over 100%<br />
* MDL-14831, MDL-15033 and MDL-16363 Issues relating to the "Sum of grades" aggregation type<br />
<br />
==Stage 2==<br />
''Nov 2010 progress update: Stage 2 has now been completed, with improvements implemented in 2.0. Items that were not completed have been bumped to stage 3 (Moodle 2.1)''<br />
<br />
For more details about these items see MDL-19131 Gradebook 2.0 - META.<br />
<br />
===Hidden activities===<br />
* MDL-19133<br />
<br />
===Gradebook help===<br />
<br />
* Review current [[Gradebook help files]] and check for consistency<br />
* MDL-13960 Make full use of title attributes in the gradebook<br />
<br />
===Centralisation of grade item settings in gradebook===<br />
* Module forms remain the same, but they draw their "Grade" section from gradebook code<br />
<br />
==Stage 3==<br />
For more details about these items see MDL-25423 Gradebook 2.1 - META. <br />
<br />
===Simplifying the gradebook further===<br />
<br />
* MDL-18049 Investigate ways of reducing the number of settings in the gradebook. Currently only grade category settings can be forced and hidden by an admin. See [[Development:Gradebook settings review]].<br />
* MDL-20250 Add admin settings for disabling gradebook features such as multiplicator, offset, calculations<br />
<br />
===Outcomes===<br />
<br />
* Review outcomes and how they are implemented in the gradebook<br />
* MDL-16103 Have an icon for outcomes on the edit categories and items page<br />
<br />
===Centralisation of grade item settings in gradebook===<br />
* Hide, Lock, Maximum Grade and other grade item settings in module forms are saved in the gradebook tables, not in module tables<br />
<br />
===Scales Refactoring===<br />
* MDL-17258 Custom non-numeric scales to have assigned numeric value in gradebook<br />
<br />
==Further changes under consideration==<br />
[[Image:Continuous grade distribution.png|thumb|Animated grade statistics report]]<br />
[[Image:Simple_grader_quick_edit_student.png|thumb|Student grades quick edit from LSU]]<br />
* MDL-15050 Grades entered in 1.9 gradebook should show in student activity report<br />
* MDL-13501 [[Student projects/Animated grade statistics report|Animated grade statistics report]] (GSoC project by Daniel Servos)<br />
* MDL-12203 Bulk message direct from the gradebook<br />
* MDL-18229 Add grade item and student grades quick edit feature to the grader report (with thanks to developers at the LSU for their [[grade/report/simple grader/quick edit|quick edit screens]])<br />
* MDL-18163 Provide summary statistics in the gradebook<br />
<br />
==See also==<br />
*[[Gradebook uses]]<br />
*[[Gradebook improvements in Moodle 1.9.5]]<br />
*[[Development talk:Gradebook improvements]]<br />
*[[Development:Gradebook settings review]]<br />
* MDL-18083 META: Gradebook improvements - Stage 1<br />
* MDL-19131 Gradebook 2.0 - META<br />
* MDL-20249 Gradebook 1.9.6 - META<br />
*[[Development:Grades]] for archive specification<br />
<br />
[[Category:Grades]]<br />
[[Category:Developer]]</div>Andyjdavishttps://docs.moodle.org/20/en/index.php?title=Development:Gradebook_improvements&diff=78304Development:Gradebook improvements2010-11-26T07:14:16Z<p>Andyjdavis: /* Stage 3 */</p>
<hr />
<div>{{Work in progress}}<br />
{{Moodle 2.0}}Improving the usability of the Moodle gradebook is one of the main targets for Moodle 2.0.<br />
<br />
This evolving page summarises a number of proposed changes, derived from community suggestions in the [http://moodle.org/mod/forum/view.php?id=2122 Gradebook forum] and in the [http://tracker.moodle.org/secure/Dashboard.jspa tracker], with special attention given to [http://tracker.moodle.org/browse/MDL/component/10062?selected=com.atlassian.jira.plugin.system.project:component-popularissues-panel the issues with the most votes].<br />
<br />
We would really like your feedback on:<br />
<br />
# The changes already proposed here<br />
# Any issues that you feel are not yet addressed<br />
<br />
We would also like your contributions to [[Gradebook uses]].<br />
<br />
Please join the discussions and post your suggestions in the [http://moodle.org/mod/forum/view.php?id=2122 Gradebook forum].<br />
<br />
<br />
==Stage 1==<br />
[[Image:Edit categories and items.png|thumb|Edit categories and items advanced settings]]<br />
''May 2009 progress update: Stage 1 has now been completed, with improvements implemented in Moodle 1.9.5 and 2.0. See [[Gradebook improvements in Moodle 1.9.5]] for details.''<br />
<br />
===Easier editing of categories and items===<br />
<br />
* MDL-16913 New "Edit categories and items" page, with hide/show advanced settings, moving of multiple items between categories and quick editing of multiple settings<br />
* MDL-17829 Combine category grade item and category edit forms<br />
<br />
===Report improvements===<br />
[[Image:Simple_grader_report_scroll.jpg|thumb|Simple grader report from LSU]]<br />
* MDL-18228 Add horizontal scrollbar in grader report to scroll grades while students stay fixed (as used in the LSU [[grade/report/simple grader/index|simple grader report]])<br />
* MDL-17991 New visual organization for gradebook user report (including category nesting, ranges)<br />
[[Image:User report.png|thumb|User report]]<br />
===Better gradebook navigation===<br />
<br />
* MDL-18004 Implement tabs navigation<br />
* MDL-12631 Grader report breadcrumbs are too long<br />
<br />
===Simplifying the gradebook===<br />
<br />
* MDL-18321 Change gradereport/overview:view default setting to 'Not set' for the role of teacher and non-editing teacher in new installs<br />
* [[Simplifying the gradebook by changing permissions]] - documentation on how to provide a simplified gradebook for teachers by changing certain permissions<br />
* MDL-12380 Add an admin setting for selecting which aggregation types are available<br />
* MDL-18523 Only display the 'Synchronise legacy grades' button when necessary<br />
<br />
===Groups access===<br />
<br />
* MDL-18119 Restrict teachers to their own groups when accessing User Reports<br />
* MDL-15617 Showing all groups in gradebook when user restricted to one<br />
<br />
===Further bug fixes and improvements===<br />
<br />
* MDL-14961 Adding a help button next to the "Synchronise legacy grades"<br />
* MDL-13417 Outcomes report is available even when outcomes are disabled<br />
* MDL-12380 Allow grades over 100%<br />
* MDL-14831, MDL-15033 and MDL-16363 Issues relating to the "Sum of grades" aggregation type<br />
<br />
==Stage 2==<br />
''Nov 2010 progress update: Stage 2 has now been completed, with improvements implemented in 2.0. Items that were not completed have been bumped to stage 3 (Moodle 2.1)''<br />
<br />
For more details about these items see MDL-19131 Gradebook 2.0 - META.<br />
<br />
===Hidden activities===<br />
* MDL-19133<br />
<br />
===Gradebook help===<br />
<br />
* Review current [[Gradebook help files]] and check for consistency<br />
* MDL-13960 Make full use of title attributes in the gradebook<br />
<br />
===Centralisation of grade item settings in gradebook===<br />
* Module forms remain the same, but they draw their "Grade" section from gradebook code<br />
<br />
==Stage 3==<br />
For more details about these items see MDL-25423 Gradebook 2.1 - META. <br />
<br />
===Simplifying the gradebook further===<br />
<br />
* MDL-18049 Investigate ways of reducing the number of settings in the gradebook. Currently only grade category settings can be forced and hidden by an admin. See [[Development:Gradebook settings review]].<br />
* MDL-20250 Add admin settings for disabling gradebook features such as multiplicator, offset, calculations<br />
<br />
===Outcomes===<br />
<br />
* Review outcomes and how they are implemented in the gradebook<br />
* MDL-16103 Have an icon for outcomes on the edit categories and items page<br />
<br />
===Centralisation of grade item settings in gradebook===<br />
* Hide, Lock, Maximum Grade and other grade item settings in module forms are saved in the gradebook tables, not in module tables<br />
<br />
==Further changes under consideration==<br />
[[Image:Continuous grade distribution.png|thumb|Animated grade statistics report]]<br />
[[Image:Simple_grader_quick_edit_student.png|thumb|Student grades quick edit from LSU]]<br />
* MDL-15050 Grades entered in 1.9 gradebook should show in student activity report<br />
* MDL-13501 [[Student projects/Animated grade statistics report|Animated grade statistics report]] (GSoC project by Daniel Servos)<br />
* MDL-12203 Bulk message direct from the gradebook<br />
* MDL-18229 Add grade item and student grades quick edit feature to the grader report (with thanks to developers at the LSU for their [[grade/report/simple grader/quick edit|quick edit screens]])<br />
* MDL-18163 Provide summary statistics in the gradebook<br />
<br />
==See also==<br />
*[[Gradebook uses]]<br />
*[[Gradebook improvements in Moodle 1.9.5]]<br />
*[[Development talk:Gradebook improvements]]<br />
*[[Development:Gradebook settings review]]<br />
* MDL-18083 META: Gradebook improvements - Stage 1<br />
* MDL-19131 Gradebook 2.0 - META<br />
* MDL-20249 Gradebook 1.9.6 - META<br />
*[[Development:Grades]] for archive specification<br />
<br />
[[Category:Grades]]<br />
[[Category:Developer]]</div>Andyjdavishttps://docs.moodle.org/20/en/index.php?title=Development:Gradebook_improvements&diff=78303Development:Gradebook improvements2010-11-26T06:41:45Z<p>Andyjdavis: /* Stage 2 */</p>
<hr />
<div>{{Work in progress}}<br />
{{Moodle 2.0}}Improving the usability of the Moodle gradebook is one of the main targets for Moodle 2.0.<br />
<br />
This evolving page summarises a number of proposed changes, derived from community suggestions in the [http://moodle.org/mod/forum/view.php?id=2122 Gradebook forum] and in the [http://tracker.moodle.org/secure/Dashboard.jspa tracker], with special attention given to [http://tracker.moodle.org/browse/MDL/component/10062?selected=com.atlassian.jira.plugin.system.project:component-popularissues-panel the issues with the most votes].<br />
<br />
We would really like your feedback on:<br />
<br />
# The changes already proposed here<br />
# Any issues that you feel are not yet addressed<br />
<br />
We would also like your contributions to [[Gradebook uses]].<br />
<br />
Please join the discussions and post your suggestions in the [http://moodle.org/mod/forum/view.php?id=2122 Gradebook forum].<br />
<br />
<br />
==Stage 1==<br />
[[Image:Edit categories and items.png|thumb|Edit categories and items advanced settings]]<br />
''May 2009 progress update: Stage 1 has now been completed, with improvements implemented in Moodle 1.9.5 and 2.0. See [[Gradebook improvements in Moodle 1.9.5]] for details.''<br />
<br />
===Easier editing of categories and items===<br />
<br />
* MDL-16913 New "Edit categories and items" page, with hide/show advanced settings, moving of multiple items between categories and quick editing of multiple settings<br />
* MDL-17829 Combine category grade item and category edit forms<br />
<br />
===Report improvements===<br />
[[Image:Simple_grader_report_scroll.jpg|thumb|Simple grader report from LSU]]<br />
* MDL-18228 Add horizontal scrollbar in grader report to scroll grades while students stay fixed (as used in the LSU [[grade/report/simple grader/index|simple grader report]])<br />
* MDL-17991 New visual organization for gradebook user report (including category nesting, ranges)<br />
[[Image:User report.png|thumb|User report]]<br />
===Better gradebook navigation===<br />
<br />
* MDL-18004 Implement tabs navigation<br />
* MDL-12631 Grader report breadcrumbs are too long<br />
<br />
===Simplifying the gradebook===<br />
<br />
* MDL-18321 Change gradereport/overview:view default setting to 'Not set' for the role of teacher and non-editing teacher in new installs<br />
* [[Simplifying the gradebook by changing permissions]] - documentation on how to provide a simplified gradebook for teachers by changing certain permissions<br />
* MDL-12380 Add an admin setting for selecting which aggregation types are available<br />
* MDL-18523 Only display the 'Synchronise legacy grades' button when necessary<br />
<br />
===Groups access===<br />
<br />
* MDL-18119 Restrict teachers to their own groups when accessing User Reports<br />
* MDL-15617 Showing all groups in gradebook when user restricted to one<br />
<br />
===Further bug fixes and improvements===<br />
<br />
* MDL-14961 Adding a help button next to the "Synchronise legacy grades"<br />
* MDL-13417 Outcomes report is available even when outcomes are disabled<br />
* MDL-12380 Allow grades over 100%<br />
* MDL-14831, MDL-15033 and MDL-16363 Issues relating to the "Sum of grades" aggregation type<br />
<br />
==Stage 2==<br />
''Nov 2010 progress update: Stage 2 has now been completed, with improvements implemented in 2.0. Items that were not completed have been bumped to stage 3 (Moodle 2.1)''<br />
<br />
For more details about these items see MDL-19131 Gradebook 2.0 - META.<br />
<br />
===Hidden activities===<br />
* MDL-19133<br />
<br />
===Gradebook help===<br />
<br />
* Review current [[Gradebook help files]] and check for consistency<br />
* MDL-13960 Make full use of title attributes in the gradebook<br />
<br />
===Centralisation of grade item settings in gradebook===<br />
* Module forms remain the same, but they draw their "Grade" section from gradebook code<br />
<br />
==Stage 3==<br />
<br />
===Simplifying the gradebook further===<br />
<br />
* MDL-18049 Investigate ways of reducing the number of settings in the gradebook. Currently only grade category settings can be forced and hidden by an admin. See [[Development:Gradebook settings review]].<br />
* MDL-20250 Add admin settings for disabling gradebook features such as multiplicator, offset, calculations<br />
<br />
===Outcomes===<br />
<br />
* Review outcomes and how they are implemented in the gradebook<br />
* MDL-16103 Have an icon for outcomes on the edit categories and items page<br />
<br />
===Centralisation of grade item settings in gradebook===<br />
* Hide, Lock, Maximum Grade and other grade item settings in module forms are saved in the gradebook tables, not in module tables<br />
<br />
==Further changes under consideration==<br />
[[Image:Continuous grade distribution.png|thumb|Animated grade statistics report]]<br />
[[Image:Simple_grader_quick_edit_student.png|thumb|Student grades quick edit from LSU]]<br />
* MDL-15050 Grades entered in 1.9 gradebook should show in student activity report<br />
* MDL-13501 [[Student projects/Animated grade statistics report|Animated grade statistics report]] (GSoC project by Daniel Servos)<br />
* MDL-12203 Bulk message direct from the gradebook<br />
* MDL-18229 Add grade item and student grades quick edit feature to the grader report (with thanks to developers at the LSU for their [[grade/report/simple grader/quick edit|quick edit screens]])<br />
* MDL-18163 Provide summary statistics in the gradebook<br />
<br />
==See also==<br />
*[[Gradebook uses]]<br />
*[[Gradebook improvements in Moodle 1.9.5]]<br />
*[[Development talk:Gradebook improvements]]<br />
*[[Development:Gradebook settings review]]<br />
* MDL-18083 META: Gradebook improvements - Stage 1<br />
* MDL-19131 Gradebook 2.0 - META<br />
* MDL-20249 Gradebook 1.9.6 - META<br />
*[[Development:Grades]] for archive specification<br />
<br />
[[Category:Grades]]<br />
[[Category:Developer]]</div>Andyjdavishttps://docs.moodle.org/20/en/index.php?title=Development:Gradebook_improvements&diff=78302Development:Gradebook improvements2010-11-26T06:40:17Z<p>Andyjdavis: /* Stage 3 */</p>
<hr />
<div>{{Work in progress}}<br />
{{Moodle 2.0}}Improving the usability of the Moodle gradebook is one of the main targets for Moodle 2.0.<br />
<br />
This evolving page summarises a number of proposed changes, derived from community suggestions in the [http://moodle.org/mod/forum/view.php?id=2122 Gradebook forum] and in the [http://tracker.moodle.org/secure/Dashboard.jspa tracker], with special attention given to [http://tracker.moodle.org/browse/MDL/component/10062?selected=com.atlassian.jira.plugin.system.project:component-popularissues-panel the issues with the most votes].<br />
<br />
We would really like your feedback on:<br />
<br />
# The changes already proposed here<br />
# Any issues that you feel are not yet addressed<br />
<br />
We would also like your contributions to [[Gradebook uses]].<br />
<br />
Please join the discussions and post your suggestions in the [http://moodle.org/mod/forum/view.php?id=2122 Gradebook forum].<br />
<br />
<br />
==Stage 1==<br />
[[Image:Edit categories and items.png|thumb|Edit categories and items advanced settings]]<br />
''May 2009 progress update: Stage 1 has now been completed, with improvements implemented in Moodle 1.9.5 and 2.0. See [[Gradebook improvements in Moodle 1.9.5]] for details.''<br />
<br />
===Easier editing of categories and items===<br />
<br />
* MDL-16913 New "Edit categories and items" page, with hide/show advanced settings, moving of multiple items between categories and quick editing of multiple settings<br />
* MDL-17829 Combine category grade item and category edit forms<br />
<br />
===Report improvements===<br />
[[Image:Simple_grader_report_scroll.jpg|thumb|Simple grader report from LSU]]<br />
* MDL-18228 Add horizontal scrollbar in grader report to scroll grades while students stay fixed (as used in the LSU [[grade/report/simple grader/index|simple grader report]])<br />
* MDL-17991 New visual organization for gradebook user report (including category nesting, ranges)<br />
[[Image:User report.png|thumb|User report]]<br />
===Better gradebook navigation===<br />
<br />
* MDL-18004 Implement tabs navigation<br />
* MDL-12631 Grader report breadcrumbs are too long<br />
<br />
===Simplifying the gradebook===<br />
<br />
* MDL-18321 Change gradereport/overview:view default setting to 'Not set' for the role of teacher and non-editing teacher in new installs<br />
* [[Simplifying the gradebook by changing permissions]] - documentation on how to provide a simplified gradebook for teachers by changing certain permissions<br />
* MDL-12380 Add an admin setting for selecting which aggregation types are available<br />
* MDL-18523 Only display the 'Synchronise legacy grades' button when necessary<br />
<br />
===Groups access===<br />
<br />
* MDL-18119 Restrict teachers to their own groups when accessing User Reports<br />
* MDL-15617 Showing all groups in gradebook when user restricted to one<br />
<br />
===Further bug fixes and improvements===<br />
<br />
* MDL-14961 Adding a help button next to the "Synchronise legacy grades"<br />
* MDL-13417 Outcomes report is available even when outcomes are disabled<br />
* MDL-12380 Allow grades over 100%<br />
* MDL-14831, MDL-15033 and MDL-16363 Issues relating to the "Sum of grades" aggregation type<br />
<br />
==Stage 2==<br />
''Nov 2010 progress update: Stage 2 has now been completed, with improvements implemented in 2.0. Items that were not completed have been bumped to stage 3 (Moodle 2.1)''<br />
<br />
For more details about these items see MDL-19131 Gradebook 2.0 - META.<br />
<br />
===Simplifying the gradebook further===<br />
<br />
* MDL-18049 Investigate ways of reducing the number of settings in the gradebook. Currently only grade category settings can be forced and hidden by an admin. See [[Development:Gradebook settings review]].<br />
* MDL-20250 Add admin settings for disabling gradebook features such as multiplicator, offset, calculations<br />
<br />
===Hidden activities===<br />
* MDL-19133<br />
<br />
===Outcomes===<br />
<br />
* Review outcomes and how they are implemented in the gradebook<br />
* MDL-16103 Have an icon for outcomes on the edit categories and items page<br />
<br />
===Gradebook help===<br />
<br />
* Review current [[Gradebook help files]] and check for consistency<br />
* MDL-13960 Make full use of title attributes in the gradebook<br />
<br />
===Centralisation of grade item settings in gradebook===<br />
* Module forms remain the same, but they draw their "Grade" section from gradebook code<br />
* Hide, Lock, Maximum Grade and other grade item settings in module forms are saved in the gradebook tables, not in module tables<br />
<br />
<br />
==Stage 3==<br />
<br />
===Simplifying the gradebook further===<br />
<br />
* MDL-18049 Investigate ways of reducing the number of settings in the gradebook. Currently only grade category settings can be forced and hidden by an admin. See [[Development:Gradebook settings review]].<br />
* MDL-20250 Add admin settings for disabling gradebook features such as multiplicator, offset, calculations<br />
<br />
===Outcomes===<br />
<br />
* Review outcomes and how they are implemented in the gradebook<br />
* MDL-16103 Have an icon for outcomes on the edit categories and items page<br />
<br />
===Centralisation of grade item settings in gradebook===<br />
* Hide, Lock, Maximum Grade and other grade item settings in module forms are saved in the gradebook tables, not in module tables<br />
<br />
==Further changes under consideration==<br />
[[Image:Continuous grade distribution.png|thumb|Animated grade statistics report]]<br />
[[Image:Simple_grader_quick_edit_student.png|thumb|Student grades quick edit from LSU]]<br />
* MDL-15050 Grades entered in 1.9 gradebook should show in student activity report<br />
* MDL-13501 [[Student projects/Animated grade statistics report|Animated grade statistics report]] (GSoC project by Daniel Servos)<br />
* MDL-12203 Bulk message direct from the gradebook<br />
* MDL-18229 Add grade item and student grades quick edit feature to the grader report (with thanks to developers at the LSU for their [[grade/report/simple grader/quick edit|quick edit screens]])<br />
* MDL-18163 Provide summary statistics in the gradebook<br />
<br />
==See also==<br />
*[[Gradebook uses]]<br />
*[[Gradebook improvements in Moodle 1.9.5]]<br />
*[[Development talk:Gradebook improvements]]<br />
*[[Development:Gradebook settings review]]<br />
* MDL-18083 META: Gradebook improvements - Stage 1<br />
* MDL-19131 Gradebook 2.0 - META<br />
* MDL-20249 Gradebook 1.9.6 - META<br />
*[[Development:Grades]] for archive specification<br />
<br />
[[Category:Grades]]<br />
[[Category:Developer]]</div>Andyjdavishttps://docs.moodle.org/20/en/index.php?title=Development:Gradebook_improvements&diff=78026Development:Gradebook improvements2010-11-22T02:56:50Z<p>Andyjdavis: </p>
<hr />
<div>{{Work in progress}}<br />
{{Moodle 2.0}}Improving the usability of the Moodle gradebook is one of the main targets for Moodle 2.0.<br />
<br />
This evolving page summarises a number of proposed changes, derived from community suggestions in the [http://moodle.org/mod/forum/view.php?id=2122 Gradebook forum] and in the [http://tracker.moodle.org/secure/Dashboard.jspa tracker], with special attention given to [http://tracker.moodle.org/browse/MDL/component/10062?selected=com.atlassian.jira.plugin.system.project:component-popularissues-panel the issues with the most votes].<br />
<br />
We would really like your feedback on:<br />
<br />
# The changes already proposed here<br />
# Any issues that you feel are not yet addressed<br />
<br />
We would also like your contributions to [[Gradebook uses]].<br />
<br />
Please join the discussions and post your suggestions in the [http://moodle.org/mod/forum/view.php?id=2122 Gradebook forum].<br />
<br />
<br />
==Stage 1==<br />
[[Image:Edit categories and items.png|thumb|Edit categories and items advanced settings]]<br />
''May 2009 progress update: Stage 1 has now been completed, with improvements implemented in Moodle 1.9.5 and 2.0. See [[Gradebook improvements in Moodle 1.9.5]] for details.''<br />
<br />
===Easier editing of categories and items===<br />
<br />
* MDL-16913 New "Edit categories and items" page, with hide/show advanced settings, moving of multiple items between categories and quick editing of multiple settings<br />
* MDL-17829 Combine category grade item and category edit forms<br />
<br />
===Report improvements===<br />
[[Image:Simple_grader_report_scroll.jpg|thumb|Simple grader report from LSU]]<br />
* MDL-18228 Add horizontal scrollbar in grader report to scroll grades while students stay fixed (as used in the LSU [[grade/report/simple grader/index|simple grader report]])<br />
* MDL-17991 New visual organization for gradebook user report (including category nesting, ranges)<br />
[[Image:User report.png|thumb|User report]]<br />
===Better gradebook navigation===<br />
<br />
* MDL-18004 Implement tabs navigation<br />
* MDL-12631 Grader report breadcrumbs are too long<br />
<br />
===Simplifying the gradebook===<br />
<br />
* MDL-18321 Change gradereport/overview:view default setting to 'Not set' for the role of teacher and non-editing teacher in new installs<br />
* [[Simplifying the gradebook by changing permissions]] - documentation on how to provide a simplified gradebook for teachers by changing certain permissions<br />
* MDL-12380 Add an admin setting for selecting which aggregation types are available<br />
* MDL-18523 Only display the 'Synchronise legacy grades' button when necessary<br />
<br />
===Groups access===<br />
<br />
* MDL-18119 Restrict teachers to their own groups when accessing User Reports<br />
* MDL-15617 Showing all groups in gradebook when user restricted to one<br />
<br />
===Further bug fixes and improvements===<br />
<br />
* MDL-14961 Adding a help button next to the "Synchronise legacy grades"<br />
* MDL-13417 Outcomes report is available even when outcomes are disabled<br />
* MDL-12380 Allow grades over 100%<br />
* MDL-14831, MDL-15033 and MDL-16363 Issues relating to the "Sum of grades" aggregation type<br />
<br />
==Stage 2==<br />
''Nov 2010 progress update: Stage 2 has now been completed, with improvements implemented in 2.0. Items that were not completed have been bumped to stage 3 (Moodle 2.1)''<br />
<br />
For more details about these items see MDL-19131 Gradebook 2.0 - META.<br />
<br />
===Simplifying the gradebook further===<br />
<br />
* MDL-18049 Investigate ways of reducing the number of settings in the gradebook. Currently only grade category settings can be forced and hidden by an admin. See [[Development:Gradebook settings review]].<br />
* MDL-20250 Add admin settings for disabling gradebook features such as multiplicator, offset, calculations<br />
<br />
===Hidden activities===<br />
* MDL-19133<br />
<br />
===Outcomes===<br />
<br />
* Review outcomes and how they are implemented in the gradebook<br />
* MDL-16103 Have an icon for outcomes on the edit categories and items page<br />
<br />
===Gradebook help===<br />
<br />
* Review current [[Gradebook help files]] and check for consistency<br />
* MDL-13960 Make full use of title attributes in the gradebook<br />
<br />
===Centralisation of grade item settings in gradebook===<br />
* Module forms remain the same, but they draw their "Grade" section from gradebook code<br />
* Hide, Lock, Maximum Grade and other grade item settings in module forms are saved in the gradebook tables, not in module tables<br />
<br />
<br />
==Stage 3==<br />
<br />
==Further changes under consideration==<br />
[[Image:Continuous grade distribution.png|thumb|Animated grade statistics report]]<br />
[[Image:Simple_grader_quick_edit_student.png|thumb|Student grades quick edit from LSU]]<br />
* MDL-15050 Grades entered in 1.9 gradebook should show in student activity report<br />
* MDL-13501 [[Student projects/Animated grade statistics report|Animated grade statistics report]] (GSoC project by Daniel Servos)<br />
* MDL-12203 Bulk message direct from the gradebook<br />
* MDL-18229 Add grade item and student grades quick edit feature to the grader report (with thanks to developers at the LSU for their [[grade/report/simple grader/quick edit|quick edit screens]])<br />
* MDL-18163 Provide summary statistics in the gradebook<br />
<br />
==See also==<br />
*[[Gradebook uses]]<br />
*[[Gradebook improvements in Moodle 1.9.5]]<br />
*[[Development talk:Gradebook improvements]]<br />
*[[Development:Gradebook settings review]]<br />
* MDL-18083 META: Gradebook improvements - Stage 1<br />
* MDL-19131 Gradebook 2.0 - META<br />
* MDL-20249 Gradebook 1.9.6 - META<br />
*[[Development:Grades]] for archive specification<br />
<br />
[[Category:Grades]]<br />
[[Category:Developer]]</div>Andyjdavishttps://docs.moodle.org/20/en/index.php?title=Converting_your_MySQL_database_to_UTF8&diff=77829Converting your MySQL database to UTF82010-11-17T07:24:29Z<p>Andyjdavis: /* Linux & Mac */</p>
<hr />
<div>This document looks at how to convert your MySQL database from the latin1 charset to UTF8. Moodle requires that your Database is now UTF8 and will not upgrade if your database is not, following the steps below will guide you in converting your database so that things once again work.<br />
<br />
==Why?==<br />
<br />
You may see the following error when upgrading your Moodle.<br />
<br />
''It is required that you store all your data in Unicode format (UTF-8). New installations must be performed into databases that have their default character set as Unicode. If you are upgrading, you should perform the UTF-8 migration process (see the Admin page).''<br />
<br />
<br />
Moodle requires UTF8 in order to provide better multilingual support and has done since Moodle 1.8. However the UTF8 check during install and upgrade has only been implemented recently and there are likely going to many users who find they are unable to upgrade because they did no set their database up correctly when they first installed Moodle, or for those who have been running Moodle from before 1.8 because they simply havn't already converted their database.<br />
<br />
For more information about UTF8 have a look at the doc on [https://docs.moodle.org/en/Unicode unicode].<br />
<br />
==Linux & Mac==<br />
<code bash><br />
mysqldump -uusername -ppassword -c -e --default-character-set=utf8 --single-transaction --skip-set-charset --add-drop-database -B dbname > dump.sql<br />
cp dump.sql dump-fixed.sql<br />
vim dump-fixed.sql<br />
:%s/DEFAULT CHARACTER SET latin1/DEFAULT CHARACTER SET utf8 COLLATE utf8_general_ci/<br />
:%s/DEFAULT CHARSET=latin1/DEFAULT CHARSET=utf8/<br />
:wq<br />
mysql -uusername -ppassword < dump-fixed.sql<br />
</code><br />
<br />
===Explained===<br />
The following steps will guide you in creating a database dumb, editing the database dump so that the correct charset and collation are used and then restoring the new database.<br />
<br />
To start please open a new terminal and move to a temp directory.<br />
<br />
<code bash><br />
mysqldump -uusername -ppassword -c -e --default-character-set=utf8 --single-transaction --skip-set-charset --add-drop-database -B dbname > dump.sql<br />
</code><br />
<br />
The first step is of course to dump out the database and of course we will use mysqldump for this. We do however need to set several arguments in order to clean up the charsets and provide a dump that is not going to cause you any problems if you are moving this database to a different database server or find yourself having to restore on a reverted system.<br />
<br />
; username : The username to access your database.<br />
; password : The password for the above user.<br />
; -c : Complete inserts for better compatibility.<br />
; -e : Extended inserts for better performance.<br />
; --default-character-set=utf8 : To set the default character set.<br />
; --single-transaction : To reduce our workload if anything goes wrong.<br />
; --skip-set-charset : Obviously not wanted or needed as we are changing it anyway.<br />
; --add-drop-database : Required so we can restore over the top of our existing database.<br />
; -B : We use this option so that our dump will contain drop table and create table syntax (which we will change the syntax for).<br />
; dbname : The name of the database to convert.<br />
<br />
When you run this command a database dump will be generated into '''dump.sql'''<br />
<br />
<code bash><br />
cp dump.sql dump-fixed.sql<br />
</code><br />
Next step is to copy dump.sql to dump-fixed.sql.<br />
<br />
We will make the desired changes within dump-fixed.sql and we will keep dump.sql as it is as a backup just in case.<br />
<br />
<code bash><br />
vim dump-fixed.sql<br />
:%s/DEFAULT CHARACTER SET latin1/DEFAULT CHARACTER SET utf8 COLLATE utf8_general_ci/<br />
:%s/DEFAULT CHARSET=latin1/DEFAULT CHARSET=utf8/<br />
:wq<br />
</code><br />
Now we need to edit the dump and correct the incorrect charsets that have been used. I have chosen to do this with VIM however you can use any search+replace editor or program. ( I choose VIM for this only because every linux user is/should be familiar with it).<br />
<br />
First we open the file using VIM, and then run the three commands.<br />
<br />
The first command replaces all instances of ''DEFAULT CHARACTER SET latin1'' with ''DEFAULT CHARACTER SET utf8 COLLATE utf8_general_ci''. This is used to fix up the database's default charset and collation.<br />
<br />
The second command replaces all instances of ''DEFAULT CHARSET=latin1'' with ''DEFAULT CHARSET=utf8''. This converts all tables from using latin1 to using UTF8.<br />
<br />
The third command simply saves it and exits.<br />
<br />
<code bash><br />
mysql -username -ppassword < m20dev2-fixed.sql<br />
</code><br />
Now that we've made the required changes we simply need to restore the database over top of the existing database. We can do this by running the above command.<br />
<br />
==Windows==<br />
Could someone who is familiar with Windows please convert the above into something that will work on Windows?<br />
There are likely several additional arguments for mysqldump you will need to specify including setting the file for output using -r to avoid newline issues.<br />
<br />
==More information==<br />
* [https://docs.moodle.org/en/Unicode Moodle docs: Unicode]</div>Andyjdavishttps://docs.moodle.org/20/en/index.php?title=Converting_your_MySQL_database_to_UTF8&diff=77828Converting your MySQL database to UTF82010-11-17T07:19:19Z<p>Andyjdavis: /* Linux & Mac */</p>
<hr />
<div>This document looks at how to convert your MySQL database from the latin1 charset to UTF8. Moodle requires that your Database is now UTF8 and will not upgrade if your database is not, following the steps below will guide you in converting your database so that things once again work.<br />
<br />
==Why?==<br />
<br />
You may see the following error when upgrading your Moodle.<br />
<br />
''It is required that you store all your data in Unicode format (UTF-8). New installations must be performed into databases that have their default character set as Unicode. If you are upgrading, you should perform the UTF-8 migration process (see the Admin page).''<br />
<br />
<br />
Moodle requires UTF8 in order to provide better multilingual support and has done since Moodle 1.8. However the UTF8 check during install and upgrade has only been implemented recently and there are likely going to many users who find they are unable to upgrade because they did no set their database up correctly when they first installed Moodle, or for those who have been running Moodle from before 1.8 because they simply havn't already converted their database.<br />
<br />
For more information about UTF8 have a look at the doc on [https://docs.moodle.org/en/Unicode unicode].<br />
<br />
==Linux & Mac==<br />
<code bash><br />
mysqldump -uusername -ppassword -c -e --default-character-set=utf8 --single-transaction --skip-set-charset --add-drop-database -B dbname > dump.sql<br />
cp dump.sql dump-fixed.sql<br />
vim dump-fixed.sql<br />
:%s/DEFAULT CHARACTER SET latin1/DEFAULT CHARACTER SET utf8 COLLATE utf8_general_ci/<br />
:%s/DEFAULT CHARSET=latin1/DEFAULT CHARSET=utf8/<br />
:wq<br />
mysql -username -ppassword < m20dev2-fixed.sql<br />
</code><br />
<br />
===Explained===<br />
The following steps will guide you in creating a database dumb, editing the database dump so that the correct charset and collation are used and then restoring the new database.<br />
<br />
To start please open a new terminal and move to a temp directory.<br />
<br />
<code bash><br />
mysqldump -uusername -ppassword -c -e --default-character-set=utf8 --single-transaction --skip-set-charset --add-drop-database -B dbname > dump.sql<br />
</code><br />
<br />
The first step is of course to dump out the database and of course we will use mysqldump for this. We do however need to set several arguments in order to clean up the charsets and provide a dump that is not going to cause you any problems if you are moving this database to a different database server or find yourself having to restore on a reverted system.<br />
<br />
; username : The username to access your database.<br />
; password : The password for the above user.<br />
; -c : Complete inserts for better compatibility.<br />
; -e : Extended inserts for better performance.<br />
; --default-character-set=utf8 : To set the default character set.<br />
; --single-transaction : To reduce our workload if anything goes wrong.<br />
; --skip-set-charset : Obviously not wanted or needed as we are changing it anyway.<br />
; --add-drop-database : Required so we can restore over the top of our existing database.<br />
; -B : We use this option so that our dump will contain drop table and create table syntax (which we will change the syntax for).<br />
; dbname : The name of the database to convert.<br />
<br />
When you run this command a database dump will be generated into '''dump.sql'''<br />
<br />
<code bash><br />
cp dump.sql dump-fixed.sql<br />
</code><br />
Next step is to copy dump.sql to dump-fixed.sql.<br />
<br />
We will make the desired changes within dump-fixed.sql and we will keep dump.sql as it is as a backup just in case.<br />
<br />
<code bash><br />
vim dump-fixed.sql<br />
:%s/DEFAULT CHARACTER SET latin1/DEFAULT CHARACTER SET utf8 COLLATE utf8_general_ci/<br />
:%s/DEFAULT CHARSET=latin1/DEFAULT CHARSET=utf8/<br />
:wq<br />
</code><br />
Now we need to edit the dump and correct the incorrect charsets that have been used. I have chosen to do this with VIM however you can use any search+replace editor or program. ( I choose VIM for this only because every linux user is/should be familiar with it).<br />
<br />
First we open the file using VIM, and then run the three commands.<br />
<br />
The first command replaces all instances of ''DEFAULT CHARACTER SET latin1'' with ''DEFAULT CHARACTER SET utf8 COLLATE utf8_general_ci''. This is used to fix up the database's default charset and collation.<br />
<br />
The second command replaces all instances of ''DEFAULT CHARSET=latin1'' with ''DEFAULT CHARSET=utf8''. This converts all tables from using latin1 to using UTF8.<br />
<br />
The third command simply saves it and exits.<br />
<br />
<code bash><br />
mysql -username -ppassword < m20dev2-fixed.sql<br />
</code><br />
Now that we've made the required changes we simply need to restore the database over top of the existing database. We can do this by running the above command.<br />
<br />
==Windows==<br />
Could someone who is familiar with Windows please convert the above into something that will work on Windows?<br />
There are likely several additional arguments for mysqldump you will need to specify including setting the file for output using -r to avoid newline issues.<br />
<br />
==More information==<br />
* [https://docs.moodle.org/en/Unicode Moodle docs: Unicode]</div>Andyjdavishttps://docs.moodle.org/20/en/index.php?title=Unicode&diff=77827Unicode2010-11-17T07:16:29Z<p>Andyjdavis: /* See also */</p>
<hr />
<div>==About unicode==<br />
<br />
[http://en.wikipedia.org/wiki/Unicode Unicode] is a character set that allows one to represent practically any language and many special characters used in science, math and technology. [[UTF-8]] is a specific encoding of Unicode used by many applications. Moodle uses UTF-8 encoding to be able to support different languages. Support was added in 1.6 and was made mandatory from 1.8 onwards.<br />
<br />
In MySQL, the database collation has to be set to unicode before the Moodle database is created. There are two different Unicode collations used: utf8_general_ci (default) and utf8_unicode_ci. The utf8_general_ci collation is slightly faster but less accurate than the utf8_unicode_ci collation in representing all the characters in languages. For this reason, Moodle tables are normally set-up using the utf8_unicode_ci collation. For a discussion of the difference between the collations see [http://dev.mysql.com/doc/refman/4.1/en/charset-unicode-sets.html the MySQL documentation].<br />
<br />
[http://www-atm.physics.ox.ac.uk/user/iwi/charmap.html Free On-line Unicode Character Map] gives you the possibility to see the different characters that are supported (or NOT!) in your browser and see which code is used if you need that. A nice feature with the characters is that you can easily enlarge the text in your browser to see them better. ([Ctrl]+[+] in Mozilla) If you are interested in Math symbols check list "22 Mathematical Operators". For Chemists looking for arrows, list "21" might be interesting.<br />
<br />
[http://www.catalysoft.com/catalog/unicode-1-1.jar Free offline java application], you must have java (ordinary, doesn't need the development environment) installed on your computer. Click on the JAR file. Chose Insert symbol, a popup with a list of categories comes, like "arrows" (but it doesn't have the group numbers).<br />
<br />
Moodle has good support for mathematical expressions in its [[TeX filter]], but using Unicode instead can sometimes be good. In some places (e.g. [[Cloze|CLOZE]] questions) the \ characters for TeX can cause problems, whereas Unicode characters won't. A user can enlarge an expression with Unicode. Things that are displayed in a dropdown list won't display TeX but can contain Unicode math symbols.<br />
<br />
==Migrating to unicode==<br />
From Moodle 1.8 onwards, a database migration utility is no longer included. There is however a [[https://docs.moodle.org/en/Converting_your_MySQL_database_to_UTF8 manual process ]].<br />
<br />
Prior to 1.6, Moodle did not support UTF-8 across all languages and the encoding in which the data was stored in the database depended upon the language used in a particular course. From Moodle 1.6 onwards, all language packs are converted to UTF-8 and different languages may be used on the same page. Moodle 1.6 and 1.7 include a utility to [[Database migration|migrate your database]] from any encoding to UTF-8.<br />
<br />
Thus, if you wish to upgrade from 1.5 or an earlier version, ''you must first upgrade to 1.6 or 1.7'', migrate your database to UTF-8, and then upgrade to 1.8. Similarly, if you are using Moodle 1.6 or 1.7 and have not yet migrated your database, you need to do so before upgrading to 1.8. Please refer to [[Upgrading to Moodle 1.6]] for additional information.<br />
<br />
== See also ==<br />
* [[UTF-8]]<br />
* [[UTF-8 and BOM]]<br />
* [[:Category:UTF-8]]<br />
* https://docs.moodle.org/en/Converting_your_MySQL_database_to_UTF8<br />
<br />
[[Category:Environment]]<br />
[[Category:UTF-8]]<br />
<br />
[[fr:Unicode]]<br />
[[de:Unicode]]</div>Andyjdavishttps://docs.moodle.org/20/en/index.php?title=Unicode&diff=77826Unicode2010-11-17T07:15:43Z<p>Andyjdavis: /* Migrating to unicode */</p>
<hr />
<div>==About unicode==<br />
<br />
[http://en.wikipedia.org/wiki/Unicode Unicode] is a character set that allows one to represent practically any language and many special characters used in science, math and technology. [[UTF-8]] is a specific encoding of Unicode used by many applications. Moodle uses UTF-8 encoding to be able to support different languages. Support was added in 1.6 and was made mandatory from 1.8 onwards.<br />
<br />
In MySQL, the database collation has to be set to unicode before the Moodle database is created. There are two different Unicode collations used: utf8_general_ci (default) and utf8_unicode_ci. The utf8_general_ci collation is slightly faster but less accurate than the utf8_unicode_ci collation in representing all the characters in languages. For this reason, Moodle tables are normally set-up using the utf8_unicode_ci collation. For a discussion of the difference between the collations see [http://dev.mysql.com/doc/refman/4.1/en/charset-unicode-sets.html the MySQL documentation].<br />
<br />
[http://www-atm.physics.ox.ac.uk/user/iwi/charmap.html Free On-line Unicode Character Map] gives you the possibility to see the different characters that are supported (or NOT!) in your browser and see which code is used if you need that. A nice feature with the characters is that you can easily enlarge the text in your browser to see them better. ([Ctrl]+[+] in Mozilla) If you are interested in Math symbols check list "22 Mathematical Operators". For Chemists looking for arrows, list "21" might be interesting.<br />
<br />
[http://www.catalysoft.com/catalog/unicode-1-1.jar Free offline java application], you must have java (ordinary, doesn't need the development environment) installed on your computer. Click on the JAR file. Chose Insert symbol, a popup with a list of categories comes, like "arrows" (but it doesn't have the group numbers).<br />
<br />
Moodle has good support for mathematical expressions in its [[TeX filter]], but using Unicode instead can sometimes be good. In some places (e.g. [[Cloze|CLOZE]] questions) the \ characters for TeX can cause problems, whereas Unicode characters won't. A user can enlarge an expression with Unicode. Things that are displayed in a dropdown list won't display TeX but can contain Unicode math symbols.<br />
<br />
==Migrating to unicode==<br />
From Moodle 1.8 onwards, a database migration utility is no longer included. There is however a [[https://docs.moodle.org/en/Converting_your_MySQL_database_to_UTF8 manual process ]].<br />
<br />
Prior to 1.6, Moodle did not support UTF-8 across all languages and the encoding in which the data was stored in the database depended upon the language used in a particular course. From Moodle 1.6 onwards, all language packs are converted to UTF-8 and different languages may be used on the same page. Moodle 1.6 and 1.7 include a utility to [[Database migration|migrate your database]] from any encoding to UTF-8.<br />
<br />
Thus, if you wish to upgrade from 1.5 or an earlier version, ''you must first upgrade to 1.6 or 1.7'', migrate your database to UTF-8, and then upgrade to 1.8. Similarly, if you are using Moodle 1.6 or 1.7 and have not yet migrated your database, you need to do so before upgrading to 1.8. Please refer to [[Upgrading to Moodle 1.6]] for additional information.<br />
<br />
== See also ==<br />
* [[UTF-8]]<br />
* [[UTF-8 and BOM]]<br />
* [[:Category:UTF-8]]<br />
<br />
[[Category:Environment]]<br />
[[Category:UTF-8]]<br />
<br />
[[fr:Unicode]]<br />
[[de:Unicode]]</div>Andyjdavishttps://docs.moodle.org/20/en/index.php?title=Converting_your_MySQL_database_to_UTF8&diff=77825Converting your MySQL database to UTF82010-11-17T07:08:42Z<p>Andyjdavis: /* Why? */</p>
<hr />
<div>This document looks at how to convert your MySQL database from the latin1 charset to UTF8. Moodle requires that your Database is now UTF8 and will not upgrade if your database is not, following the steps below will guide you in converting your database so that things once again work.<br />
<br />
==Why?==<br />
<br />
You may see the following error when upgrading your Moodle.<br />
<br />
''It is required that you store all your data in Unicode format (UTF-8). New installations must be performed into databases that have their default character set as Unicode. If you are upgrading, you should perform the UTF-8 migration process (see the Admin page).''<br />
<br />
<br />
Moodle requires UTF8 in order to provide better multilingual support and has done since Moodle 1.8. However the UTF8 check during install and upgrade has only been implemented recently and there are likely going to many users who find they are unable to upgrade because they did no set their database up correctly when they first installed Moodle, or for those who have been running Moodle from before 1.8 because they simply havn't already converted their database.<br />
<br />
For more information about UTF8 have a look at the doc on [https://docs.moodle.org/en/Unicode unicode].<br />
<br />
==Linux & Mac==<br />
<code bash><br />
mysqldump -uusername -ppassword -c -e --default-character-set=utf8 --single-transaction --skip-set-charset --add-drop-database -B dbname > dump.sql<br />
cp dump.sql dump-fixed.sql<br />
:%s/DEFAULT CHARACTER SET latin1/DEFAULT CHARACTER SET utf8 COLLATE utf8_general_ci/<br />
:%s/DEFAULT CHARSET=latin1/DEFAULT CHARSET=utf8/<br />
:wq<br />
mysql -username -ppassword < m20dev2-fixed.sql<br />
</code><br />
<br />
===Explained===<br />
The following steps will guide you in creating a database dumb, editing the database dump so that the correct charset and collation are used and then restoring the new database.<br />
<br />
To start please open a new terminal and move to a temp directory.<br />
<br />
<code bash><br />
mysqldump -uusername -ppassword -c -e --default-character-set=utf8 --single-transaction --skip-set-charset --add-drop-database -B dbname > dump.sql<br />
</code><br />
<br />
The first step is of course to dump out the database and of course we will use mysqldump for this. We do however need to set several arguments in order to clean up the charsets and provide a dump that is not going to cause you any problems if you are moving this database to a different database server or find yourself having to restore on a reverted system.<br />
<br />
; username : The username to access your database.<br />
; password : The password for the above user.<br />
; -c : Complete inserts for better compatibility.<br />
; -e : Extended inserts for better performance.<br />
; --default-character-set=utf8 : To set the default character set.<br />
; --single-transaction : To reduce our workload if anything goes wrong.<br />
; --skip-set-charset : Obviously not wanted or needed as we are changing it anyway.<br />
; --add-drop-database : Required so we can restore over the top of our existing database.<br />
; -B : We use this option so that our dump will contain drop table and create table syntax (which we will change the syntax for).<br />
; dbname : The name of the database to convert.<br />
<br />
When you run this command a database dump will be generated into '''dump.sql'''<br />
<br />
<code bash><br />
cp dump.sql dump-fixed.sql<br />
</code><br />
Next step is to copy dump.sql to dump-fixed.sql.<br />
<br />
We will make the desired changes within dump-fixed.sql and we will keep dump.sql as it is as a backup just in case.<br />
<br />
<code bash><br />
vim dump-fixed.sql<br />
:%s/DEFAULT CHARACTER SET latin1/DEFAULT CHARACTER SET utf8 COLLATE utf8_general_ci/<br />
:%s/DEFAULT CHARSET=latin1/DEFAULT CHARSET=utf8/<br />
:wq<br />
</code><br />
Now we need to edit the dump and correct the incorrect charsets that have been used. I have chosen to do this with VIM however you can use any search+replace editor or program. ( I choose VIM for this only because every linux user is/should be familiar with it).<br />
<br />
First we open the file using VIM, and then run the three commands.<br />
<br />
The first command replaces all instances of ''DEFAULT CHARACTER SET latin1'' with ''DEFAULT CHARACTER SET utf8 COLLATE utf8_general_ci''. This is used to fix up the database's default charset and collation.<br />
<br />
The second command replaces all instances of ''DEFAULT CHARSET=latin1'' with ''DEFAULT CHARSET=utf8''. This converts all tables from using latin1 to using UTF8.<br />
<br />
The third command simply saves it and exits.<br />
<br />
<code bash><br />
mysql -username -ppassword < m20dev2-fixed.sql<br />
</code><br />
Now that we've made the required changes we simply need to restore the database over top of the existing database. We can do this by running the above command.<br />
<br />
==Windows==<br />
Could someone who is familiar with Windows please convert the above into something that will work on Windows?<br />
There are likely several additional arguments for mysqldump you will need to specify including setting the file for output using -r to avoid newline issues.<br />
<br />
==More information==<br />
* [https://docs.moodle.org/en/Unicode Moodle docs: Unicode]</div>Andyjdavishttps://docs.moodle.org/20/en/index.php?title=Development:Messaging_2.0&diff=77602Development:Messaging 2.02010-11-09T06:59:24Z<p>Andyjdavis: /* Providers (input) */</p>
<hr />
<div>The messaging system in 2.0 has been revamped significantly. It is now event-driven, and allows users to control exactly what messages they receive and how.<br />
<br />
<br />
==How to enable it==<br />
<br />
Admin > Optional subsystems > Enable messaging system = Yes<br />
<br />
<br />
==How to configure it==<br />
<br />
Visit your own profile page (you need '''moodle/user:editownmessageprofile''' permission). Note that the types of messages listed in the "Configure destinations for incoming messages" box is determined by the contents of the message_providers table.<br />
<br />
[[Image:Messagingconfig.png]]<br />
<br />
==How it works==<br />
<br />
===Providers (input)===<br />
We have [[Development:Events|Events]] called "message_send" that look like this:<br />
<br />
<code php><br />
$eventdata = new object();<br />
$eventdata->component = 'mod_forum'; // the component sending the message. Along with name this must exist in the table message_providers<br />
$eventdata->name = 'posts'; // type of message from that module (as module defines it). Along with component this must exist in the table message_providers<br />
$eventdata->userfrom = $userfrom; // user object<br />
$eventdata->userto = $userto; // user object<br />
$eventdata->subject = $postsubject; // very short one-line subject<br />
$eventdata->fullmessage = $posttext; // raw text<br />
$eventdata->fullmessageformat = FORMAT_PLAIN; // text format<br />
$eventdata->fullmessagehtml = $posthtml; // html rendered version<br />
$eventdata->smallmessage = ''; // useful for plugins like sms or twitter<br />
<br />
events_trigger('message_send', $eventdata);<br />
</code><br />
<br />
The name of each provider is a string with a name like messageprovider:$name from the component lang file (in this case, forum.php is derived automatically from mod/forum):<br />
<br />
<code php><br />
$string['messageprovider:posts'] = 'Subscribed forum posts';<br />
$string['messageprovider:digests'] = 'Subscribed forum digests';<br />
</code><br />
<br />
More providers can be added throughout Moodle as necessary, it's quite easy. See the [[Development:Events|Events API]] for info.<br />
<br />
===Processors (output)===<br />
<br />
In [http://cvs.moodle.org/moodle/message/output /message/output] there are full Moodle plugins for each type of output. <br />
<br />
Currently we have support for email, jabber and web-based popups. Could add twitter and SMS quite easily.<br />
<br />
Each plugin simply extends a class called "message_output" in [http://cvs.moodle.org/moodle/message/output/lib.php /message/output/lib.php] with methods such as:<br />
<br />
<code php><br />
function send_message($message) {<br />
// Given a message object and user info, this actually sends it.<br />
}<br />
<br />
function config_form($preferences) {<br />
// This defines the little form fragment on the config page<br />
}<br />
<br />
function process_form($form, &$preferences) {<br />
// This processes the data from the config form fragment<br />
}<br />
<br />
function load_data(&$preferences, $userid) {<br />
// This loads up prefs for this plugin<br />
}<br />
</code><br />
<br />
It should also provide a messageprocessor_xxxxx.php language file (where xxxxx is the name) and inside is an xxxxx string with the name of the processor, like this:<br />
<br />
<code php><br />
$string['jabber'] = 'Jabber message';<br />
</code><br />
<br />
Finally, there should be a '''lib.php file''' containing an install routine to install itself as a message processor:<br />
<br />
<code php><br />
function jabber_install(){<br />
global $DB;<br />
<br />
$result = true;<br />
<br />
$provider = new object();<br />
$provider->name = 'jabber';<br />
if (!$DB->insert_record('message_processors', $provider)) {<br />
$result = false;<br />
}<br />
return $result;<br />
}<br />
</code><br />
<br />
And a '''version.php''' file:<br />
<code php><br />
$plugin->version = 2008090900;<br />
$plugin->requires = 2008091500;<br />
</code><br />
<br />
==See also==<br />
<br />
* [[GSOC/2008]]<br />
* [[Student projects/Messaging improvements|Messaging improvements]], a GSOC 2007 project<br />
* [[Development:Events|Events API]]<br />
* MDL-10107<br />
<br />
[[Category:Messaging]]<br />
[[Category:Developer]]</div>Andyjdavishttps://docs.moodle.org/20/en/index.php?title=Development:Messaging_2.0&diff=77601Development:Messaging 2.02010-11-09T06:49:47Z<p>Andyjdavis: /* Providers (input) */</p>
<hr />
<div>The messaging system in 2.0 has been revamped significantly. It is now event-driven, and allows users to control exactly what messages they receive and how.<br />
<br />
<br />
==How to enable it==<br />
<br />
Admin > Optional subsystems > Enable messaging system = Yes<br />
<br />
<br />
==How to configure it==<br />
<br />
Visit your own profile page (you need '''moodle/user:editownmessageprofile''' permission). Note that the types of messages listed in the "Configure destinations for incoming messages" box is determined by the contents of the message_providers table.<br />
<br />
[[Image:Messagingconfig.png]]<br />
<br />
==How it works==<br />
<br />
===Providers (input)===<br />
We have [[Development:Events|Events]] called "message_send" that look like this:<br />
<br />
<code php><br />
$eventdata = new object();<br />
$eventdata->component = 'mod_forum'; // the component sending the message. Must exist in message_providers<br />
$eventdata->name = 'posts'; // type of message from that module (as module defines it). Must exist in message_providers<br />
$eventdata->userfrom = $userfrom; // user object<br />
$eventdata->userto = $userto; // user object<br />
$eventdata->subject = $postsubject; // very short one-line subject<br />
$eventdata->fullmessage = $posttext; // raw text<br />
$eventdata->fullmessageformat = FORMAT_PLAIN; // text format<br />
$eventdata->fullmessagehtml = $posthtml; // html rendered version<br />
$eventdata->smallmessage = ''; // useful for plugins like sms or twitter<br />
<br />
events_trigger('message_send', $eventdata);<br />
</code><br />
<br />
The name of each provider is a string with a name like messageprovider:$name from the component lang file (in this case, forum.php is derived automatically from mod/forum):<br />
<br />
<code php><br />
$string['messageprovider:posts'] = 'Subscribed forum posts';<br />
$string['messageprovider:digests'] = 'Subscribed forum digests';<br />
</code><br />
<br />
More providers can be added throughout Moodle as necessary, it's quite easy. See the [[Development:Events|Events API]] for info.<br />
<br />
===Processors (output)===<br />
<br />
In [http://cvs.moodle.org/moodle/message/output /message/output] there are full Moodle plugins for each type of output. <br />
<br />
Currently we have support for email, jabber and web-based popups. Could add twitter and SMS quite easily.<br />
<br />
Each plugin simply extends a class called "message_output" in [http://cvs.moodle.org/moodle/message/output/lib.php /message/output/lib.php] with methods such as:<br />
<br />
<code php><br />
function send_message($message) {<br />
// Given a message object and user info, this actually sends it.<br />
}<br />
<br />
function config_form($preferences) {<br />
// This defines the little form fragment on the config page<br />
}<br />
<br />
function process_form($form, &$preferences) {<br />
// This processes the data from the config form fragment<br />
}<br />
<br />
function load_data(&$preferences, $userid) {<br />
// This loads up prefs for this plugin<br />
}<br />
</code><br />
<br />
It should also provide a messageprocessor_xxxxx.php language file (where xxxxx is the name) and inside is an xxxxx string with the name of the processor, like this:<br />
<br />
<code php><br />
$string['jabber'] = 'Jabber message';<br />
</code><br />
<br />
Finally, there should be a '''lib.php file''' containing an install routine to install itself as a message processor:<br />
<br />
<code php><br />
function jabber_install(){<br />
global $DB;<br />
<br />
$result = true;<br />
<br />
$provider = new object();<br />
$provider->name = 'jabber';<br />
if (!$DB->insert_record('message_processors', $provider)) {<br />
$result = false;<br />
}<br />
return $result;<br />
}<br />
</code><br />
<br />
And a '''version.php''' file:<br />
<code php><br />
$plugin->version = 2008090900;<br />
$plugin->requires = 2008091500;<br />
</code><br />
<br />
==See also==<br />
<br />
* [[GSOC/2008]]<br />
* [[Student projects/Messaging improvements|Messaging improvements]], a GSOC 2007 project<br />
* [[Development:Events|Events API]]<br />
* MDL-10107<br />
<br />
[[Category:Messaging]]<br />
[[Category:Developer]]</div>Andyjdavishttps://docs.moodle.org/20/en/index.php?title=Development:Messaging_2.0&diff=77599Development:Messaging 2.02010-11-09T06:26:37Z<p>Andyjdavis: /* How to configure it */</p>
<hr />
<div>The messaging system in 2.0 has been revamped significantly. It is now event-driven, and allows users to control exactly what messages they receive and how.<br />
<br />
<br />
==How to enable it==<br />
<br />
Admin > Optional subsystems > Enable messaging system = Yes<br />
<br />
<br />
==How to configure it==<br />
<br />
Visit your own profile page (you need '''moodle/user:editownmessageprofile''' permission). Note that the types of messages listed in the "Configure destinations for incoming messages" box is determined by the contents of the message_providers table.<br />
<br />
[[Image:Messagingconfig.png]]<br />
<br />
==How it works==<br />
<br />
===Providers (input)===<br />
We have [[Development:Events|Events]] called "message_send" that look like this:<br />
<br />
<code php><br />
$eventdata = new object();<br />
$eventdata->component = 'mod/forum'; // path in Moodle<br />
$eventdata->name = 'posts'; // type of message from that module (as module defines it)<br />
$eventdata->userfrom = $userfrom; // user object<br />
$eventdata->userto = $userto; // user object<br />
$eventdata->subject = $postsubject; // very short one-line subject<br />
$eventdata->fullmessage = $posttext; // raw text<br />
$eventdata->fullmessageformat = FORMAT_PLAIN; // text format<br />
$eventdata->fullmessagehtml = $posthtml; // html rendered version<br />
$eventdata->smallmessage = ''; // useful for plugins like sms or twitter<br />
<br />
events_trigger('message_send', $eventdata);<br />
</code><br />
<br />
The name of each provider is a string with a name like messageprovider:$name from the component lang file (in this case, forum.php is derived automatically from mod/forum):<br />
<br />
<code php><br />
$string['messageprovider:posts'] = 'Subscribed forum posts';<br />
$string['messageprovider:digests'] = 'Subscribed forum digests';<br />
</code><br />
<br />
More providers can be added throughout Moodle as necessary, it's quite easy. See the [[Development:Events|Events API]] for info.<br />
<br />
===Processors (output)===<br />
<br />
In [http://cvs.moodle.org/moodle/message/output /message/output] there are full Moodle plugins for each type of output. <br />
<br />
Currently we have support for email, jabber and web-based popups. Could add twitter and SMS quite easily.<br />
<br />
Each plugin simply extends a class called "message_output" in [http://cvs.moodle.org/moodle/message/output/lib.php /message/output/lib.php] with methods such as:<br />
<br />
<code php><br />
function send_message($message) {<br />
// Given a message object and user info, this actually sends it.<br />
}<br />
<br />
function config_form($preferences) {<br />
// This defines the little form fragment on the config page<br />
}<br />
<br />
function process_form($form, &$preferences) {<br />
// This processes the data from the config form fragment<br />
}<br />
<br />
function load_data(&$preferences, $userid) {<br />
// This loads up prefs for this plugin<br />
}<br />
</code><br />
<br />
It should also provide a messageprocessor_xxxxx.php language file (where xxxxx is the name) and inside is an xxxxx string with the name of the processor, like this:<br />
<br />
<code php><br />
$string['jabber'] = 'Jabber message';<br />
</code><br />
<br />
Finally, there should be a '''lib.php file''' containing an install routine to install itself as a message processor:<br />
<br />
<code php><br />
function jabber_install(){<br />
global $DB;<br />
<br />
$result = true;<br />
<br />
$provider = new object();<br />
$provider->name = 'jabber';<br />
if (!$DB->insert_record('message_processors', $provider)) {<br />
$result = false;<br />
}<br />
return $result;<br />
}<br />
</code><br />
<br />
And a '''version.php''' file:<br />
<code php><br />
$plugin->version = 2008090900;<br />
$plugin->requires = 2008091500;<br />
</code><br />
<br />
==See also==<br />
<br />
* [[GSOC/2008]]<br />
* [[Student projects/Messaging improvements|Messaging improvements]], a GSOC 2007 project<br />
* [[Development:Events|Events API]]<br />
* MDL-10107<br />
<br />
[[Category:Messaging]]<br />
[[Category:Developer]]</div>Andyjdavishttps://docs.moodle.org/20/en/index.php?title=Development:Forum_notifications_as_messages&diff=76869Development:Forum notifications as messages2010-10-20T02:28:41Z<p>Andyjdavis: /* Possible solutions */</p>
<hr />
<div>{{Moodle 2.0}}<br />
<br />
<p class="note">WARNING: Under construction RIGHT NOW!</p><br />
<br />
==The problems==<br />
Forum notifications are now done via the messaging system rather than by the forum sending out emails itself. This reduces duplicate code and, once more modules report events via messaging, allows users to view what amounts to an activity feed for their contacts instead of just their personal messages.<br />
<br />
Unfortunately forum notifications currently appear on /message/index.php in a form which is proving to be annoying and confusing on a site with busy forums. There two closely related problems:<br />
<br />
[[Image:Forumnotificationsinmessaging.gif]]<br />
<br />
* Each forum post notification consumes a lot of screen real estate. See the screenshot for an example. This makes the whole interface less usable as it requires lots of scrolling past unnecessary and repeated text.<br />
<br />
* Forum notifications appear to be coming from the author of the forum post causing them to be displayed among personal messages exchanged by the two users with no clear indication of what is going on. For example if two users, Mary and John, are having a conversation via personal messages and Mary posts in a forum, John's notification of that post will appear among their personal messages. This is potentially confusing.<br />
<br />
==Possible solutions==<br />
* (DONE) Reduce the real estate consumed by forum notifications (MDL-24563). The notification message could be reviewed to reduce its overall size. Additionally, with IMs the version that is displayed on /message/index.php doesn't include the footer that is appended to the emailed version. This condenses their display and prevents the inclusion of standard boilerplate like "This is a copy of a message posted on the CF101 website" on the messaging screen. The messaging system supports both "smallmessage" and "fullmessage" but we do not currently make use of this. If we utilize them both processors and the messaging UI can choose which to display For example the forum post notifications small message could be set to something like this (then displayed on the messaging screen):<br />
<br />
<br />
Andrew posted in (forum name)<br />
<br />
(Andrew's post content)<br />
<br />
To view: (link to the post)<br />
<br />
<br />
with the full message, used by the email processor, looking something like this:<br />
<br />
<br />
This is a copy of a message posted in CF101 -> Forums -> (forum name) -> (discussion name)<br />
<br />
Andrew posted in (forum name)<br />
<br />
(Andrew's post content)<br />
<br />
To view: (link to the post)<br />
<br />
To unsubscribe from this forum: (unsubscribe link)<br />
<br />
<br />
* Differentiate messages and notifications (MDL-24771). Add a new column called notification to the message table (and maybe message_read) to flag messages that are notifications rather than a message from another user. Messages continue to be read and then moved to message_read and displayed on /message/index.php as they are now. However, messages that are marked as notifications could be dealt with by the message processors then either deleted or moved to message_read and ignored by the code that retrieves the messages to display on /message/index.php Alternatively, once we can tell notifications from personal messages, notifications could continue to be displayed on /message/index.php but css could be used to visually differentiate between messages and notifications. If we were going to do this we'd most like want to also do #1.<br />
<br />
* Try to avoid putting forum notifications through the messaging system. When the forum cron code is constructing the forum post notifications instead of handing them over to the messaging system it could check the user's messaging preferences and if they have selected ONLY email as handler for forum posts it could send the emails itself and simply not use the messaging system. Popup and Jabber notifications would still need to be handled by the messaging code so this measure would mitigate but not fully resolve the issue.<br />
<br />
* Are there any other alternatives?<br />
<br />
:Here is one idea:<br />
<br />
:Change message.useridfrom to message.contextidfrom. That would not messages not only come from other users, but it would also let things like "Forum X" but the sender of the message. That seems like a more sensible option.<br />
<br />
:Of course, for outputs like email, you would then need some way of constructing a from email address for that notional sender. Hmm.--[[User:Tim Hunt|Tim Hunt]] 09:49, 11 October 2010 (UTC)<br />
<br />
:Why not add contextidfrom in addition to userid from? That way it can say 'in General Development Forum (from sam marshall)' or something, and it knows how to use from addresses [supposing you have the 'from real address' option turned on] [[User:sam marshall|sam marshall]] 09:08, 12 October 2010 (UTC)</div>Andyjdavishttps://docs.moodle.org/20/en/index.php?title=Development:Forum_notifications_as_messages&diff=76799Development:Forum notifications as messages2010-10-15T07:08:00Z<p>Andyjdavis: /* Possible solutions */</p>
<hr />
<div>{{Moodle 2.0}}<br />
<br />
<p class="note">WARNING: Under construction RIGHT NOW!</p><br />
<br />
==The problems==<br />
Forum notifications are now done via the messaging system rather than by the forum sending out emails itself. This reduces duplicate code and, once more modules report events via messaging, allows users to view what amounts to an activity feed for their contacts instead of just their personal messages.<br />
<br />
Unfortunately forum notifications currently appear on /message/index.php in a form which is proving to be annoying and confusing on a site with busy forums. There two closely related problems:<br />
<br />
[[Image:Forumnotificationsinmessaging.gif]]<br />
<br />
* Each forum post notification consumes a lot of screen real estate. See the screenshot for an example. This makes the whole interface less usable as it requires lots of scrolling past unnecessary and repeated text.<br />
<br />
* Forum notifications appear to be coming from the author of the forum post causing them to be displayed among personal messages exchanged by the two users with no clear indication of what is going on. For example if two users, Mary and John, are having a conversation via personal messages and Mary posts in a forum, John's notification of that post will appear among their personal messages. This is potentially confusing.<br />
<br />
==Possible solutions==<br />
* (DONE) Reduce the real estate consumed by forum notifications. See MDL-24563 The notification message could be reviewed to reduce its overall size. Additionally, with IMs the version that is displayed on /message/index.php doesn't include the footer that is appended to the emailed version. This condenses their display and prevents the inclusion of standard boilerplate like "This is a copy of a message posted on the CF101 website" on the messaging screen. The messaging system supports both "smallmessage" and "fullmessage" but we do not currently make use of this. If we utilize them both processors and the messaging UI can choose which to display For example the forum post notifications small message could be set to something like this (then displayed on the messaging screen):<br />
<br />
<br />
Andrew posted in (forum name)<br />
<br />
(Andrew's post content)<br />
<br />
To view: (link to the post)<br />
<br />
<br />
with the full message, used by the email processor, looking something like this:<br />
<br />
<br />
This is a copy of a message posted in CF101 -> Forums -> (forum name) -> (discussion name)<br />
<br />
Andrew posted in (forum name)<br />
<br />
(Andrew's post content)<br />
<br />
To view: (link to the post)<br />
<br />
To unsubscribe from this forum: (unsubscribe link)<br />
<br />
<br />
* Differentiate messages and notifications. Add a new column called notification to the message table (and maybe message_read) to flag messages that are notifications rather than a message from another user. Messages continue to be read and then moved to message_read and displayed on /message/index.php as they are now. However, messages that are marked as notifications could be dealt with by the message processors then either deleted or moved to message_read and ignored by the code that retrieves the messages to display on /message/index.php Alternatively, once we can tell notifications from personal messages, notifications could continue to be displayed on /message/index.php but css could be used to visually differentiate between messages and notifications. If we were going to do this we'd most like want to also do #1.<br />
<br />
* Try to avoid putting forum notifications through the messaging system. When the forum cron code is constructing the forum post notifications instead of handing them over to the messaging system it could check the user's messaging preferences and if they have selected ONLY email as handler for forum posts it could send the emails itself and simply not use the messaging system. Popup and Jabber notifications would still need to be handled by the messaging code so this measure would mitigate but not fully resolve the issue.<br />
<br />
* Are there any other alternatives?<br />
<br />
:Here is one idea:<br />
<br />
:Change message.useridfrom to message.contextidfrom. That would not messages not only come from other users, but it would also let things like "Forum X" but the sender of the message. That seems like a more sensible option.<br />
<br />
:Of course, for outputs like email, you would then need some way of constructing a from email address for that notional sender. Hmm.--[[User:Tim Hunt|Tim Hunt]] 09:49, 11 October 2010 (UTC)<br />
<br />
:Why not add contextidfrom in addition to userid from? That way it can say 'in General Development Forum (from sam marshall)' or something, and it knows how to use from addresses [supposing you have the 'from real address' option turned on] [[User:sam marshall|sam marshall]] 09:08, 12 October 2010 (UTC)</div>Andyjdavishttps://docs.moodle.org/20/en/index.php?title=Development:Forum_notifications_as_messages&diff=76733Development:Forum notifications as messages2010-10-12T08:49:51Z<p>Andyjdavis: /* Possible solutions */</p>
<hr />
<div>{{Moodle 2.0}}<br />
<br />
<p class="note">WARNING: Under construction RIGHT NOW!</p><br />
<br />
==The problems==<br />
Forum notifications are now done via the messaging system rather than by the forum sending out emails itself. This reduces duplicate code and, once more modules report events via messaging, allows users to view what amounts to an activity feed for their contacts instead of just their personal messages.<br />
<br />
Unfortunately forum notifications currently appear on /message/index.php in a form which is proving to be annoying and confusing on a site with busy forums. There two closely related problems:<br />
<br />
[[Image:Forumnotificationsinmessaging.gif]]<br />
<br />
* Each forum post notification consumes a lot of screen real estate. See the screenshot for an example. This makes the whole interface less usable as it requires lots of scrolling past unnecessary and repeated text.<br />
<br />
* Forum notifications appear to be coming from the author of the forum post causing them to be displayed among personal messages exchanged by the two users with no clear indication of what is going on. For example if two users, Mary and John, are having a conversation via personal messages and Mary posts in a forum, John's notification of that post will appear among their personal messages. This is potentially confusing.<br />
<br />
==Possible solutions==<br />
* Reduce the real estate consumed by forum notifications. See MDL-24563 The notification message could be reviewed to reduce its overall size. Additionally, with IMs the version that is displayed on /message/index.php doesn't include the footer that is appended to the emailed version. This condenses their display and prevents the inclusion of standard boilerplate like "This is a copy of a message posted on the CF101 website" on the messaging screen. The messaging system could be further enhanced to accommodate forum notifications by allowing the calling code to supply a header and footer which are included in the emails but not saved as part of the message. For example the forum post notifications on the messaging page could be reduced to something like this:<br />
<br />
<br />
Andrew posted in (forum name)<br />
<br />
(Andrew's post content)<br />
<br />
To reply: (link to the post)<br />
<br />
<br />
with the version being emailed looking something like this:<br />
<br />
<br />
This is a copy of a message posted in CF101 -> Forums -> (forum name) -> (discussion name)<br />
<br />
Andrew posted in (forum name)<br />
<br />
(Andrew's post content)<br />
<br />
To reply: (link to the post)<br />
<br />
To unsubscribe from this forum: (unsubscribe link)<br />
<br />
<br />
* Differentiate messages and notifications. Add a new column called notification to the message table (and maybe message_read) to flag messages that are notifications rather than a message from another user. Messages continue to be read and then moved to message_read and displayed on /message/index.php as they are now. However, messages that are marked as notifications could be dealt with by the message processors then either deleted or moved to message_read and ignored by the code that retrieves the messages to display on /message/index.php Alternatively, once we can tell notifications from personal messages, notifications could continue to be displayed on /message/index.php but css could be used to visually differentiate between messages and notifications. If we were going to do this we'd most like want to also do #1.<br />
<br />
* Try to avoid putting forum notifications through the messaging system. When the forum cron code is constructing the forum post notifications instead of handing them over to the messaging system it could check the user's messaging preferences and if they have selected ONLY email as handler for forum posts it could send the emails itself and simply not use the messaging system. Popup and Jabber notifications would still need to be handled by the messaging code so this measure would mitigate but not fully resolve the issue.<br />
<br />
* Are there any other alternatives?<br />
<br />
:Here is one idea:<br />
<br />
:Change message.useridfrom to message.contextidfrom. That would not messages not only come from other users, but it would also let things like "Forum X" but the sender of the message. That seems like a more sensible option.<br />
<br />
:Of course, for outputs like email, you would then need some way of constructing a from email address for that notional sender. Hmm.--[[User:Tim Hunt|Tim Hunt]] 09:49, 11 October 2010 (UTC)</div>Andyjdavishttps://docs.moodle.org/20/en/index.php?title=Development:Forum_notifications_as_messages&diff=76719Development:Forum notifications as messages2010-10-11T03:52:26Z<p>Andyjdavis: /* Possible solutions */</p>
<hr />
<div>{{Moodle 2.0}}<br />
<br />
<p class="note">WARNING: Under construction RIGHT NOW!</p><br />
<br />
==The problems==<br />
Forum notifications are now done via the messaging system rather than by the forum sending out emails itself. This reduces duplicate code and, once more modules report events via messaging, allows users to view what amounts to an activity feed for their contacts instead of just their personal messages.<br />
<br />
Unfortunately forum notifications currently appear on /message/index.php in a form which is proving to be annoying and confusing on a site with busy forums. There two closely related problems:<br />
<br />
[[Image:Forumnotificationsinmessaging.gif]]<br />
<br />
* Each forum post notification consumes a lot of screen real estate. See the screenshot for an example. This makes the whole interface less usable as it requires lots of scrolling past unnecessary and repeated text.<br />
<br />
* Forum notifications appear to be coming from the author of the forum post causing them to be displayed among personal messages exchanged by the two users with no clear indication of what is going on. For example if two users, Mary and John, are having a conversation via personal messages and Mary posts in a forum, John's notification of that post will appear among their personal messages. This is potentially confusing.<br />
<br />
==Possible solutions==<br />
* Reduce the real estate consumed by forum notifications. The notification message could be reviewed to reduce its overall size. Additionally, with IMs the version that is displayed on /message/index.php doesn't include the footer that is appended to the emailed version. This condenses their display and prevents the inclusion of standard boilerplate like "This is a copy of a message posted on the CF101 website" on the messaging screen. The messaging system could be further enhanced to accommodate forum notifications by allowing the calling code to supply a header and footer which are included in the emails but not saved as part of the message. For example the forum post notifications on the messaging page could be reduced to something like this:<br />
<br />
<br />
Andrew posted in (forum name)<br />
<br />
(Andrew's post content)<br />
<br />
To reply: (link to the post)<br />
<br />
<br />
with the version being emailed looking something like this:<br />
<br />
<br />
This is a copy of a message posted in CF101 -> Forums -> (forum name) -> (discussion name)<br />
<br />
Andrew posted in (forum name)<br />
<br />
(Andrew's post content)<br />
<br />
To reply: (link to the post)<br />
<br />
To unsubscribe from this forum: (unsubscribe link)<br />
<br />
<br />
* Differentiate messages and notifications. Add a new column called notification to the message table (and maybe message_read) to flag messages that are notifications rather than a message from another user. Messages continue to be read and then moved to message_read and displayed on /message/index.php as they are now. However, messages that are marked as notifications could be dealt with by the message processors then either deleted or moved to message_read and ignored by the code that retrieves the messages to display on /message/index.php Alternatively, once we can tell notifications from personal messages, notifications could continue to be displayed on /message/index.php but css could be used to visually differentiate between messages and notifications. If we were going to do this we'd most like want to also do #1.<br />
<br />
* Try to avoid putting forum notifications through the messaging system. When the forum cron code is constructing the forum post notifications instead of handing them over to the messaging system it could check the user's messaging preferences and if they have selected ONLY email as handler for forum posts it could send the emails itself and simply not use the messaging system. Popup and Jabber notifications would still need to be handled by the messaging code so this measure would mitigate but not fully resolve the issue.<br />
<br />
* Are there any other alternatives?</div>Andyjdavishttps://docs.moodle.org/20/en/index.php?title=Development:Forum_notifications_as_messages&diff=76718Development:Forum notifications as messages2010-10-11T03:51:22Z<p>Andyjdavis: /* Possible solutions */</p>
<hr />
<div>{{Moodle 2.0}}<br />
<br />
<p class="note">WARNING: Under construction RIGHT NOW!</p><br />
<br />
==The problems==<br />
Forum notifications are now done via the messaging system rather than by the forum sending out emails itself. This reduces duplicate code and, once more modules report events via messaging, allows users to view what amounts to an activity feed for their contacts instead of just their personal messages.<br />
<br />
Unfortunately forum notifications currently appear on /message/index.php in a form which is proving to be annoying and confusing on a site with busy forums. There two closely related problems:<br />
<br />
[[Image:Forumnotificationsinmessaging.gif]]<br />
<br />
* Each forum post notification consumes a lot of screen real estate. See the screenshot for an example. This makes the whole interface less usable as it requires lots of scrolling past unnecessary and repeated text.<br />
<br />
* Forum notifications appear to be coming from the author of the forum post causing them to be displayed among personal messages exchanged by the two users with no clear indication of what is going on. For example if two users, Mary and John, are having a conversation via personal messages and Mary posts in a forum, John's notification of that post will appear among their personal messages. This is potentially confusing.<br />
<br />
==Possible solutions==<br />
# Reduce the real estate consumed by forum notifications. The notification message could be reviewed to reduce its overall size. Additionally, with IMs the version that is displayed on /message/index.php doesn't include the footer that is appended to the emailed version. This condenses their display and prevents the inclusion of standard boilerplate like "This is a copy of a message posted on the CF101 website" on the messaging screen. The messaging system could be further enhanced to accommodate forum notifications by allowing the calling code to supply a header and footer which are included in the emails but not saved as part of the message. For example the forum post notifications on the messaging page could be reduced to something like this:<br />
<br />
<br />
Andrew posted in (forum name)<br />
<br />
(Andrew's post content)<br />
<br />
To reply: (link to the post)<br />
<br />
<br />
with the version being emailed looking something like this:<br />
<br />
<br />
This is a copy of a message posted in CF101 -> Forums -> (forum name) -> (discussion name)<br />
<br />
Andrew posted in (forum name)<br />
<br />
(Andrew's post content)<br />
<br />
To reply: (link to the post)<br />
<br />
To unsubscribe from this forum: (unsubscribe link)<br />
<br />
<br />
# Differentiate messages and notifications. Add a new column called notification to the message table (and maybe message_read) to flag messages that are notifications rather than a message from another user. Messages continue to be read and then moved to message_read and displayed on /message/index.php as they are now. However, messages that are marked as notifications could be dealt with by the message processors then either deleted or moved to message_read and ignored by the code that retrieves the messages to display on /message/index.php Alternatively, once we can tell notifications from personal messages, notifications could continue to be displayed on /message/index.php but css could be used to visually differentiate between messages and notifications. If we were going to do this we'd most like want to also do #1.<br />
<br />
# Try to avoid putting forum notifications through the messaging system. When the forum cron code is constructing the forum post notifications instead of handing them over to the messaging system it could check the user's messaging preferences and if they have selected ONLY email as handler for forum posts it could send the emails itself and simply not use the messaging system. Popup and Jabber notifications would still need to be handled by the messaging code so this measure would mitigate but not fully resolve the issue.<br />
<br />
# Are there any other alternatives?</div>Andyjdavishttps://docs.moodle.org/20/en/index.php?title=Development:Forum_notifications_as_messages&diff=76717Development:Forum notifications as messages2010-10-11T03:48:10Z<p>Andyjdavis: /* The problems */</p>
<hr />
<div>{{Moodle 2.0}}<br />
<br />
<p class="note">WARNING: Under construction RIGHT NOW!</p><br />
<br />
==The problems==<br />
Forum notifications are now done via the messaging system rather than by the forum sending out emails itself. This reduces duplicate code and, once more modules report events via messaging, allows users to view what amounts to an activity feed for their contacts instead of just their personal messages.<br />
<br />
Unfortunately forum notifications currently appear on /message/index.php in a form which is proving to be annoying and confusing on a site with busy forums. There two closely related problems:<br />
<br />
[[Image:Forumnotificationsinmessaging.gif]]<br />
<br />
* Each forum post notification consumes a lot of screen real estate. See the screenshot for an example. This makes the whole interface less usable as it requires lots of scrolling past unnecessary and repeated text.<br />
<br />
* Forum notifications appear to be coming from the author of the forum post causing them to be displayed among personal messages exchanged by the two users with no clear indication of what is going on. For example if two users, Mary and John, are having a conversation via personal messages and Mary posts in a forum, John's notification of that post will appear among their personal messages. This is potentially confusing.<br />
<br />
==Possible solutions==<br />
# Reduce the real estate consumed by forum notifications. The notification message could be reviewed to reduce its overall size. Additionally, with IMs the version that is displayed on /message/index.php doesn't include the footer that is appended to the emailed version. This condenses their display and prevents the inclusion of standard boilerplate like "This is a copy of a message posted on the CF101 website" on the messaging screen. The messaging system could be enhanced to allow the calling code to supply a header and footer which could be included in the emails but then discarded. Ideally the forum posts notifications on the messaging page could be reduced to something like the following:<br />
<br />
<br />
Andrew posted in (forum name)<br />
<br />
(Andrew's post content)<br />
<br />
To reply: (link to the post)<br />
<br />
<br />
with the version being emailed looking something like this:<br />
<br />
<br />
This is a copy of a message posted in CF101 -> Forums -> (forum name) -> (discussion name)<br />
<br />
Andrew posted in (forum name)<br />
<br />
(Andrew's post content)<br />
<br />
To reply: (link to the post)<br />
<br />
To unsubscribe from this forum: (unsubscribe link)<br />
<br />
<br />
# Differentiate messages and notifications. Add a new column called notification to the message table (and maybe message_read) to flag messages that are notifications rather than a message from another user. Messages continue to be read and then moved to message_read and displayed on /message/index.php as they are now. However, messages that are marked as notifications could be dealt with then either deleted or moved to message_read and ignored by the code that retrieves the messages to display on /message/index.php Alternatively, once we can tell notifications from personal messages, notifications could continue to be displayed on /message/index.php but css could be used to visually differentiate between messages and notifications. If we were going to do this we'd most like want to also do #1.<br />
<br />
# Try to avoid putting forum notifications through the messaging system. When the forum cron code is constructing the forum post notifications instead of handing them over to the messaging system it could check the user's messaging preferences and if they have selected ONLY email as handler for forum posts it could send the emails itself and simply not use the messaging system. Popup and Jabber notifications would still need to be handled by the messaging code so this measure would mitigate but not fully resolve the issue.<br />
<br />
# Are there any other alternatives?</div>Andyjdavishttps://docs.moodle.org/20/en/index.php?title=Development:Forum_notifications_as_messages&diff=76716Development:Forum notifications as messages2010-10-11T03:42:26Z<p>Andyjdavis: /* The problems */</p>
<hr />
<div>{{Moodle 2.0}}<br />
<br />
<p class="note">WARNING: Under construction RIGHT NOW!</p><br />
<br />
==The problems==<br />
Forum notifications are now done via the messaging system rather than by the forum sending out emails itself. Unfortunately forum notifications then appear on /message/index.php in a form which is proving to be annoying and confusing on a site with busy forums. There two closely related problems:<br />
<br />
[[Image:Forumnotificationsinmessaging.gif]]<br />
<br />
* Each forum post notification consumes a lot of screen real estate. See the screenshot for an example. This makes the whole interface less usable as it requires lots of scrolling past unnecessary and repeated text.<br />
<br />
* Forum notifications appear to be coming from the author of the forum post and so are displayed among personal messages exchanged by the two users. For example if two users, Mary and John, are having a conversation via personal messages and Mary posts in a forum, John's notification of that post will appear among their personal messages as if it were a message from Mary. This is potentially confusing and interrupts the flow of conversation.<br />
<br />
==Possible solutions==<br />
# Reduce the real estate consumed by forum notifications. The notification message could be reviewed to reduce its overall size. Additionally, with IMs the version that is displayed on /message/index.php doesn't include the footer that is appended to the emailed version. This condenses their display and prevents the inclusion of standard boilerplate like "This is a copy of a message posted on the CF101 website" on the messaging screen. The messaging system could be enhanced to allow the calling code to supply a header and footer which could be included in the emails but then discarded. Ideally the forum posts notifications on the messaging page could be reduced to something like the following:<br />
<br />
<br />
Andrew posted in (forum name)<br />
<br />
(Andrew's post content)<br />
<br />
To reply: (link to the post)<br />
<br />
<br />
with the version being emailed looking something like this:<br />
<br />
<br />
This is a copy of a message posted in CF101 -> Forums -> (forum name) -> (discussion name)<br />
<br />
Andrew posted in (forum name)<br />
<br />
(Andrew's post content)<br />
<br />
To reply: (link to the post)<br />
<br />
To unsubscribe from this forum: (unsubscribe link)<br />
<br />
<br />
# Differentiate messages and notifications. Add a new column called notification to the message table (and maybe message_read) to flag messages that are notifications rather than a message from another user. Messages continue to be read and then moved to message_read and displayed on /message/index.php as they are now. However, messages that are marked as notifications could be dealt with then either deleted or moved to message_read and ignored by the code that retrieves the messages to display on /message/index.php Alternatively, once we can tell notifications from personal messages, notifications could continue to be displayed on /message/index.php but css could be used to visually differentiate between messages and notifications. If we were going to do this we'd most like want to also do #1.<br />
<br />
# Try to avoid putting forum notifications through the messaging system. When the forum cron code is constructing the forum post notifications instead of handing them over to the messaging system it could check the user's messaging preferences and if they have selected ONLY email as handler for forum posts it could send the emails itself and simply not use the messaging system. Popup and Jabber notifications would still need to be handled by the messaging code so this measure would mitigate but not fully resolve the issue.<br />
<br />
# Are there any other alternatives?</div>Andyjdavishttps://docs.moodle.org/20/en/index.php?title=Development:Forum_notifications_as_messages&diff=76715Development:Forum notifications as messages2010-10-11T03:41:41Z<p>Andyjdavis: /* The problems */</p>
<hr />
<div>{{Moodle 2.0}}<br />
<br />
<p class="note">WARNING: Under construction RIGHT NOW!</p><br />
<br />
==The problems==<br />
Forum notifications are now done via the messaging system rather than by the forum sending out emails itself. Unfortunately forum notifications then appear on /message/index.php in a form which is proving to be annoying and confusing on a site with busy forums. There two closely related problems:<br />
<br />
[[Image:Forumnotificationsinmessaging.gif]]<br />
<br />
* Each forum post notification consumes a lot of screen real estate. See the screenshot for an example. This makes the whole interface less usable as it requires lots of scrolling past unnecessary and repeated text.<br />
<br />
* Forum notifications appear to be coming from the author of the forum post and so are displayed among personal messages exchanged by the two users. For example if two users, Mary and John, are having a conversation via personal messages and Mary posts in a forum, John's notification of that post will appear among their personal messages as if it were a personal message from Mary. This is potentially confusing and interrupts the flow of conversation.<br />
<br />
==Possible solutions==<br />
# Reduce the real estate consumed by forum notifications. The notification message could be reviewed to reduce its overall size. Additionally, with IMs the version that is displayed on /message/index.php doesn't include the footer that is appended to the emailed version. This condenses their display and prevents the inclusion of standard boilerplate like "This is a copy of a message posted on the CF101 website" on the messaging screen. The messaging system could be enhanced to allow the calling code to supply a header and footer which could be included in the emails but then discarded. Ideally the forum posts notifications on the messaging page could be reduced to something like the following:<br />
<br />
<br />
Andrew posted in (forum name)<br />
<br />
(Andrew's post content)<br />
<br />
To reply: (link to the post)<br />
<br />
<br />
with the version being emailed looking something like this:<br />
<br />
<br />
This is a copy of a message posted in CF101 -> Forums -> (forum name) -> (discussion name)<br />
<br />
Andrew posted in (forum name)<br />
<br />
(Andrew's post content)<br />
<br />
To reply: (link to the post)<br />
<br />
To unsubscribe from this forum: (unsubscribe link)<br />
<br />
<br />
# Differentiate messages and notifications. Add a new column called notification to the message table (and maybe message_read) to flag messages that are notifications rather than a message from another user. Messages continue to be read and then moved to message_read and displayed on /message/index.php as they are now. However, messages that are marked as notifications could be dealt with then either deleted or moved to message_read and ignored by the code that retrieves the messages to display on /message/index.php Alternatively, once we can tell notifications from personal messages, notifications could continue to be displayed on /message/index.php but css could be used to visually differentiate between messages and notifications. If we were going to do this we'd most like want to also do #1.<br />
<br />
# Try to avoid putting forum notifications through the messaging system. When the forum cron code is constructing the forum post notifications instead of handing them over to the messaging system it could check the user's messaging preferences and if they have selected ONLY email as handler for forum posts it could send the emails itself and simply not use the messaging system. Popup and Jabber notifications would still need to be handled by the messaging code so this measure would mitigate but not fully resolve the issue.<br />
<br />
# Are there any other alternatives?</div>Andyjdavishttps://docs.moodle.org/20/en/index.php?title=Development:Forum_notifications_as_messages&diff=76714Development:Forum notifications as messages2010-10-11T03:40:36Z<p>Andyjdavis: /* The problems */</p>
<hr />
<div>{{Moodle 2.0}}<br />
<br />
<p class="note">WARNING: Under construction RIGHT NOW!</p><br />
<br />
==The problems==<br />
Forum notifications are now done via the messaging system rather than by the forum sending out emails itself. Unfortunately forum notifications then appear on /message/index.php in a forum which is proving to be annoying and confusing on a site with busy forums. There two closely related problems:<br />
<br />
[[Image:Forumnotificationsinmessaging.gif]]<br />
<br />
* Each forum post notification consumes a lot of screen real estate. See the screenshot for an example. This makes the whole interface less usable as it requires lots of scrolling past unnecessary and repeated text.<br />
<br />
* Forum notifications appear to be coming from the author of the forum post and so are displayed among personal messages exchanged by the two users. For example if two users, Mary and John, are having a conversation via personal messages and Mary posts in a forum, John's notification of that post will appear among their personal messages as if it were a personal message from Mary. This is potentially confusing and interrupts the flow of conversation.<br />
<br />
==Possible solutions==<br />
# Reduce the real estate consumed by forum notifications. The notification message could be reviewed to reduce its overall size. Additionally, with IMs the version that is displayed on /message/index.php doesn't include the footer that is appended to the emailed version. This condenses their display and prevents the inclusion of standard boilerplate like "This is a copy of a message posted on the CF101 website" on the messaging screen. The messaging system could be enhanced to allow the calling code to supply a header and footer which could be included in the emails but then discarded. Ideally the forum posts notifications on the messaging page could be reduced to something like the following:<br />
<br />
<br />
Andrew posted in (forum name)<br />
<br />
(Andrew's post content)<br />
<br />
To reply: (link to the post)<br />
<br />
<br />
with the version being emailed looking something like this:<br />
<br />
<br />
This is a copy of a message posted in CF101 -> Forums -> (forum name) -> (discussion name)<br />
<br />
Andrew posted in (forum name)<br />
<br />
(Andrew's post content)<br />
<br />
To reply: (link to the post)<br />
<br />
To unsubscribe from this forum: (unsubscribe link)<br />
<br />
<br />
# Differentiate messages and notifications. Add a new column called notification to the message table (and maybe message_read) to flag messages that are notifications rather than a message from another user. Messages continue to be read and then moved to message_read and displayed on /message/index.php as they are now. However, messages that are marked as notifications could be dealt with then either deleted or moved to message_read and ignored by the code that retrieves the messages to display on /message/index.php Alternatively, once we can tell notifications from personal messages, notifications could continue to be displayed on /message/index.php but css could be used to visually differentiate between messages and notifications. If we were going to do this we'd most like want to also do #1.<br />
<br />
# Try to avoid putting forum notifications through the messaging system. When the forum cron code is constructing the forum post notifications instead of handing them over to the messaging system it could check the user's messaging preferences and if they have selected ONLY email as handler for forum posts it could send the emails itself and simply not use the messaging system. Popup and Jabber notifications would still need to be handled by the messaging code so this measure would mitigate but not fully resolve the issue.<br />
<br />
# Are there any other alternatives?</div>Andyjdavishttps://docs.moodle.org/20/en/index.php?title=Development:Forum_notifications_as_messages&diff=76713Development:Forum notifications as messages2010-10-11T03:39:09Z<p>Andyjdavis: /* Possible solutions */</p>
<hr />
<div>{{Moodle 2.0}}<br />
<br />
<p class="note">WARNING: Under construction RIGHT NOW!</p><br />
<br />
==The problems==<br />
Forum notifications are now done via the messaging system rather than by the forum sending out emails itself. Unfortunately forum notifications then appear on /message/index.php which is proving to be annoying and confusing on a site with busy forums. There two closely related problems:<br />
<br />
[[Image:Forumnotificationsinmessaging.gif]]<br />
<br />
* Each forum post notification consumes a lot of screen real estate. See the screenshot for an example. This makes the whole interface less usable as it requires lots of scrolling past unnecessary and repeated text.<br />
<br />
* Forum notifications appear to be coming from the author of the forum post and so are displayed among personal messages exchanged by the two users. For example if two users, Mary and John, are having a conversation via personal messages and Mary posts in a forum, John's notification of that post will appear among their personal messages as if it were a personal message from Mary. This is potentially confusing and interrupts the flow of conversation.<br />
<br />
==Possible solutions==<br />
# Reduce the real estate consumed by forum notifications. The notification message could be reviewed to reduce its overall size. Additionally, with IMs the version that is displayed on /message/index.php doesn't include the footer that is appended to the emailed version. This condenses their display and prevents the inclusion of standard boilerplate like "This is a copy of a message posted on the CF101 website" on the messaging screen. The messaging system could be enhanced to allow the calling code to supply a header and footer which could be included in the emails but then discarded. Ideally the forum posts notifications on the messaging page could be reduced to something like the following:<br />
<br />
<br />
Andrew posted in (forum name)<br />
<br />
(Andrew's post content)<br />
<br />
To reply: (link to the post)<br />
<br />
<br />
with the version being emailed looking something like this:<br />
<br />
<br />
This is a copy of a message posted in CF101 -> Forums -> (forum name) -> (discussion name)<br />
<br />
Andrew posted in (forum name)<br />
<br />
(Andrew's post content)<br />
<br />
To reply: (link to the post)<br />
<br />
To unsubscribe from this forum: (unsubscribe link)<br />
<br />
<br />
# Differentiate messages and notifications. Add a new column called notification to the message table (and maybe message_read) to flag messages that are notifications rather than a message from another user. Messages continue to be read and then moved to message_read and displayed on /message/index.php as they are now. However, messages that are marked as notifications could be dealt with then either deleted or moved to message_read and ignored by the code that retrieves the messages to display on /message/index.php Alternatively, once we can tell notifications from personal messages, notifications could continue to be displayed on /message/index.php but css could be used to visually differentiate between messages and notifications. If we were going to do this we'd most like want to also do #1.<br />
<br />
# Try to avoid putting forum notifications through the messaging system. When the forum cron code is constructing the forum post notifications instead of handing them over to the messaging system it could check the user's messaging preferences and if they have selected ONLY email as handler for forum posts it could send the emails itself and simply not use the messaging system. Popup and Jabber notifications would still need to be handled by the messaging code so this measure would mitigate but not fully resolve the issue.<br />
<br />
# Are there any other alternatives?</div>Andyjdavishttps://docs.moodle.org/20/en/index.php?title=Development:Forum_notifications_as_messages&diff=76712Development:Forum notifications as messages2010-10-11T03:37:19Z<p>Andyjdavis: /* Possible solutions */</p>
<hr />
<div>{{Moodle 2.0}}<br />
<br />
<p class="note">WARNING: Under construction RIGHT NOW!</p><br />
<br />
==The problems==<br />
Forum notifications are now done via the messaging system rather than by the forum sending out emails itself. Unfortunately forum notifications then appear on /message/index.php which is proving to be annoying and confusing on a site with busy forums. There two closely related problems:<br />
<br />
[[Image:Forumnotificationsinmessaging.gif]]<br />
<br />
* Each forum post notification consumes a lot of screen real estate. See the screenshot for an example. This makes the whole interface less usable as it requires lots of scrolling past unnecessary and repeated text.<br />
<br />
* Forum notifications appear to be coming from the author of the forum post and so are displayed among personal messages exchanged by the two users. For example if two users, Mary and John, are having a conversation via personal messages and Mary posts in a forum, John's notification of that post will appear among their personal messages as if it were a personal message from Mary. This is potentially confusing and interrupts the flow of conversation.<br />
<br />
==Possible solutions==<br />
# Reduce the real estate consumed by forum notifications. The notification message could be reviewed to reduce its overall size. Additionally, with IMs the version that is displayed on /message/index.php doesn't include the footer that is appended to the emailed version. This condenses their display and prevents the inclusion of standard boilerplate like "This is a copy of a message posted on the CF101 website" on the messaging screen. The messaging system could be enhanced to allow the calling code to supply a header and footer which could be included in the emails but then discarded. Ideally the forum posts notifications on the messaging page could be reduced to something like the following:<br />
<br />
<br />
Andrew posted in (forum name)<br />
<br />
(Andrew's post content)<br />
<br />
To reply: (link to the post)<br />
<br />
<br />
with the version being emailed looking something like this:<br />
<br />
<br />
This is a copy of a message posted in CF101 -> Forums -> (forum name) -> (discussion name)<br />
<br />
Andrew posted in (forum name)<br />
<br />
(Andrew's post content)<br />
<br />
To reply: (link to the post)<br />
<br />
To unsubscribe from this forum: (unsubscribe link)<br />
<br />
<br />
# Differentiate messages and notifications. Add a new column called notification to the message table (and maybe message_read) to flag messages that are notifications rather than a message from another user. Messages continue to be read and then moved to message_read and displayed on /message/index.php as they are now. However, messages that are marked as notifications could be dealt with then either deleted or moved to message_read and ignored by the code that retrieves the messages to display on /message/index.php Alternatively, once we can tell notifications from personal messages, notifications could continue to be displayed on /message/index.php but css could be used to visually differentiate between messages and notifications.<br />
<br />
# Try to avoid putting forum notifications through the messaging system. When the forum cron code is constructing the forum post notifications instead of handing them over to the messaging system it could check the user's messaging preferences and if they have selected ONLY email as handler for forum posts it could send the emails itself and simply not use the messaging system. Popup and Jabber notifications would still need to be handled by the messaging code so this measure would mitigate but not fully resolve the issue.<br />
<br />
# Are there any other alternatives?</div>Andyjdavis