MDL-62535 core_grading: Update to providers and interface.

The previous interface was inadequate for retrieving user
information stored in the sub-plugins.

A new interface and methods have been added to successfully
deal with user data.
This commit is contained in:
Adrian Greeve 2018-06-14 10:38:19 +08:00 committed by Adrian Greeve
parent a9428fab11
commit f3a6d9bb76
9 changed files with 273 additions and 18 deletions

View File

@ -26,8 +26,6 @@ namespace core_grading\privacy;
defined('MOODLE_INTERNAL') || die();
use core_privacy\local\request\approved_contextlist;
/**
* The trait used to provide backwards compatability for third-party plugins.
*
@ -36,9 +34,32 @@ use core_privacy\local\request\approved_contextlist;
*/
trait gradingform_legacy_polyfill {
/**
* Export user data relating to an instance ID.
*
* @param \context $context Context to use with the export writer.
* @param int $instanceid The instance ID to export data for.
* @param array $subcontext The directory to export this data to.
*/
public static function export_gradingform_instance_data(\context $context, int $instanceid, array $subcontext) {
static::_export_gradingform_instance_data($context, $instanceid, $subcontext);
}
/**
* Deletes all user data related to the provided instance IDs.
*
* @param array $instanceids The instance IDs to delete information from.
*/
public static function delete_gradingform_for_instances(array $instanceids) {
static::_delete_gradingform_for_instances($instanceids);
}
/**
* This method is used to export any user data this sub-plugin has using the object to get the context and userid.
*
* @deprecated Since Moodle 3.6 MDL-62535 Please use the methods in the gradingform_provider_v2 interface.
* @todo MDL-63137 remove this method.
*
* @param context $context Context owner of the data.
* @param stdClass $definition Grading definition entry to export.
* @param int $userid The user whose information is to be exported.
@ -46,25 +67,34 @@ trait gradingform_legacy_polyfill {
* @return stdClass The data to export.
*/
public static function get_gradingform_export_data(\context $context, $definition, int $userid) {
debugging('This method is deprecated. Please use the gradingform_provider_v2 interface', DEBUG_DEVELOPER);
return static::_get_gradingform_export_data($context, $definition, $userid);
}
/**
* Any call to this method should delete all user data for the context defined.
*
* @deprecated Since Moodle 3.6 MDL-62535 Please use the methods in the gradingform_provider_v2 interface.
* @todo MDL-63137 remove this method.
*
* @param context $context Context owner of the data.
*/
public static function delete_gradingform_for_context(\context $context) {
debugging('This method is deprecated. Please use the gradingform_provider_v2 interface', DEBUG_DEVELOPER);
static::_delete_gradingform_for_context($context);
}
/**
* A call to this method should delete user data (where practicle) from the userid and context.
*
* @deprecated Since Moodle 3.6 MDL-62535 Please use the methods in the gradingform_provider_v2 interface.
* @todo MDL-63137 remove this method.
*
* @param int $userid The user whose information is to be deleted.
* @param context $context Context owner of the data.
*/
public static function delete_gradingform_for_userid(int $userid, \context $context) {
debugging('This method is deprecated. Please use the gradingform_provider_v2 interface', DEBUG_DEVELOPER);
static::_delete_gradingform_for_userid($userid, $context);
}
}

View File

@ -19,6 +19,9 @@
*
* Grading method plugins should implement this if they store personal information.
*
* @deprecated since Moodle 3.6 MDL-62535 Please use the gradingform_provider_v2 interface
* @todo MDL-63167 Remove this file.
*
* @package core_grading
* @copyright 2018 Sara Arjona <sara@moodle.com>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
@ -31,11 +34,15 @@ defined('MOODLE_INTERNAL') || die();
use core_privacy\local\request\approved_contextlist;
interface gradingform_provider extends
\core_privacy\local\request\plugin\subsystem_provider {
\core_privacy\local\request\plugin\subsystem_provider,
\core_privacy\local\deprecated {
/**
* This method is used to export any user data this sub-plugin has using the object to get the context and userid.
*
* @deprecated since Moodle 3.6 MDL-62535 Please use the methods in the gradingform_provider_v2 interface
* @todo MDL-63167 Remove this file.
*
* @param \context $context Context owner of the data.
* @param \stdClass $definition Grading definition entry to export.
* @param int $userid The user whose information is to be exported.
@ -47,6 +54,9 @@ interface gradingform_provider extends
/**
* Any call to this method should delete all user data for the context defined.
*
* @deprecated since Moodle 3.6 MDL-62535 Please use the methods in the gradingform_provider_v2 interface
* @todo MDL-63167 Remove this file.
*
* @param \context $context Context owner of the data.
*/
public static function delete_gradingform_for_context(\context $context);
@ -54,6 +64,9 @@ interface gradingform_provider extends
/**
* A call to this method should delete user data (where practicle) from the userid and context.
*
* @deprecated since Moodle 3.6 MDL-62535 Please use the methods in the gradingform_provider_v2 interface
* @todo MDL-63167 Remove this file.
*
* @param int $userid The user to delete.
* @param \context $context the context to refine the deletion.
*/

View File

@ -0,0 +1,46 @@
<?php
// This file is part of Moodle - http://moodle.org/
//
// Moodle is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Moodle is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
/**
* Privacy class for requesting user data.
*
* @package core_grading
* @copyright 2018 Adrian Greeve <adriangreeve.com>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
namespace core_grading\privacy;
defined('MOODLE_INTERNAL') || die();
interface gradingform_provider_v2 extends
\core_privacy\local\request\plugin\subsystem_provider {
/**
* Export user data relating to an instance ID.
*
* @param \context $context Context to use with the export writer.
* @param int $instanceid The instance ID to export data for.
* @param array $subcontext The directory to export this data to.
*/
public static function export_gradingform_instance_data(\context $context, int $instanceid, array $subcontext);
/**
* Deletes all user data related to the provided instance IDs.
*
* @param array $instanceids The instance IDs to delete information from.
*/
public static function delete_gradingform_for_instances(array $instanceids);
}

View File

@ -133,6 +133,73 @@ class provider implements
}
}
/**
* Export all user data related to a context and itemid.
*
* @param \context $context Context to export on.
* @param int $itemid Item ID to export on.
* @param array $subcontext Directory location to export to.
*/
public static function export_item_data(\context $context, int $itemid, array $subcontext) {
global $DB;
$sql = "SELECT gi.id AS instanceid, gd.id AS definitionid, gd.method
FROM {grading_areas} ga
JOIN {grading_definitions} gd ON gd.areaid = ga.id
JOIN {grading_instances} gi ON gi.definitionid = gd.id AND gi.itemid = :itemid
WHERE ga.contextid = :contextid";
$params = [
'itemid' => $itemid,
'contextid' => $context->id,
];
$records = $DB->get_recordset_sql($sql, $params);
foreach ($records as $record) {
$instancedata = manager::component_class_callback(
"gradingform_{$record->method}",
gradingform_provider_v2::class,
'export_gradingform_instance_data',
[$context, $record->instanceid, $subcontext]
);
}
$records->close();
}
/**
* Deletes all user data related to a context and possibly an itemid.
*
* @param \context $context The context to delete on.
* @param int|null $itemid An optional item ID to refine the deletion.
*/
public static function delete_instance_data(\context $context, int $itemid = null) {
global $DB;
$itemsql = '';
$params = ['contextid' => $context->id];
if (isset($itemid)) {
$params['itemid'] = $itemid;
$itemsql = 'AND gi.itemid = :itemid';
}
$sql = "SELECT gi.id AS instanceid, gd.id, gd.method
FROM {grading_definitions} gd
JOIN {grading_instances} gi ON gi.definitionid = gd.id
JOIN {grading_areas} ga ON ga.id = gd.areaid
WHERE ga.contextid = :contextid $itemsql";
$records = $DB->get_records_sql($sql, $params);
if ($records) {
$firstrecord = current($records);
$method = $firstrecord->method;
$instanceids = array_map(function($record) {
return $record->instanceid;
}, $records);
manager::component_class_callback(
"gradingform_{$method}",
gradingform_provider_v2::class,
'delete_gradingform_for_instances',
[$instanceids]);
// Delete grading_instances rows.
$DB->delete_records_list('grading_instances', 'id', $instanceids);
}
}
/**
* Exports the data related to grading definitions within the specified context/subcontext.
*
@ -191,6 +258,8 @@ class provider implements
if (!empty($definition->timecopied)) {
$tmpdata['timecopied'] = transform::datetime($definition->timecopied);
}
// MDL-63167 - This section is to be removed with the final deprecation of the gradingform_provider interface.
// Export gradingform information (if needed).
$instancedata = manager::component_class_callback(
"gradingform_{$definition->method}",
@ -201,6 +270,7 @@ class provider implements
if (null !== $instancedata) {
$tmpdata = array_merge($tmpdata, $instancedata);
}
// End of section to be removed with deprecation.
$defdata[] = (object) $tmpdata;
@ -258,34 +328,35 @@ class provider implements
}
/**
* Delete all use data which matches the specified $context.
* No deletion of the advanced grading is done.
*
* We never delete grading content.
*
* @param context $context A user context.
* @param \context $context the context to delete in.
*/
public static function delete_data_for_all_users_in_context(\context $context) {
// MDL-63167 - This section is to be removed with the final deprecation of the gradingform_provider interface.
manager::plugintype_class_callback(
'gradingform',
gradingform_provider::class,
'delete_gradingform_for_context',
[$context]
);
// End of section to be removed for final deprecation.
}
/**
* Delete all user data for the specified user, in the specified contexts.
* Deletion of data in this provider is only related to grades and so can not be
* deleted for the creator of the advanced grade criteria.
*
* We never delete grading content.
*
* @param approved_contextlist $contextlist The approved contexts and user information to delete information for.
* @param approved_contextlist $contextlist a list of contexts approved for deletion.
*/
public static function delete_data_for_user(approved_contextlist $contextlist) {
// MDL-63167 - This section is to be removed with the final deprecation of the gradingform_provider interface.
manager::plugintype_class_callback(
'gradingform',
gradingform_provider::class,
'delete_gradingform_for_userid',
[$contextlist]
);
// End of section to be removed for final deprecation.
}
}

View File

@ -38,6 +38,7 @@ use \core_privacy\local\request\writer;
*/
class provider implements
\core_privacy\local\metadata\provider,
\core_grading\privacy\gradingform_provider_v2,
\core_privacy\local\request\user_preference_provider {
/**
@ -47,6 +48,12 @@ class provider implements
* @return collection A listing of user data stored through this system.
*/
public static function get_metadata(collection $collection) : collection {
$collection->add_database_table('gradingform_guide_fillings', [
'instanceid' => 'privacy:metadata:instanceid',
'criterionid' => 'privacy:metadata:criterionid',
'remark' => 'privacy:metadata:remark',
'score' => 'privacy:metadata:score'
], 'privacy:metadata:fillingssummary');
$collection->add_user_preference(
'gradingform_guide-showmarkerdesc',
'privacy:metadata:preference:showmarkerdesc'
@ -59,6 +66,38 @@ class provider implements
return $collection;
}
/**
* Export user data relating to an instance ID.
*
* @param \context $context Context to use with the export writer.
* @param int $instanceid The instance ID to export data for.
* @param array $subcontext The directory to export this data to.
*/
public static function export_gradingform_instance_data(\context $context, int $instanceid, array $subcontext) {
global $DB;
// Get records from the provided params.
$params = ['instanceid' => $instanceid];
$sql = "SELECT gc.shortname, gc.description, gc.maxscore, gf.score, gf.remark
FROM {gradingform_guide_fillings} gf
JOIN {gradingform_guide_criteria} gc ON gc.id = gf.criterionid
WHERE gf.instanceid = :instanceid";
$records = $DB->get_records_sql($sql, $params);
if ($records) {
$subcontext = array_merge($subcontext, [get_string('guide', 'gradingform_guide')]);
writer::with_context($context)->export_data($subcontext, (object) $records);
}
}
/**
* Deletes all user data related to the provided instance IDs.
*
* @param array $instanceids The instance IDs to delete information from.
*/
public static function delete_gradingform_for_instances(array $instanceids) {
global $DB;
$DB->delete_records_list('gradingform_guide_fillings', 'instanceid', $instanceids);
}
/**
* Store all user preferences for the plugin.
*

View File

@ -75,8 +75,13 @@ $string['name'] = 'Name';
$string['needregrademessage'] = 'The marking guide definition was changed after this student had been graded. The student can not see this marking guide until you check the marking guide and update the grade.';
$string['pluginname'] = 'Marking guide';
$string['previewmarkingguide'] = 'Preview marking guide';
$string['privacy:metadata:criterionid'] = 'An identifier to a criterion for advanced marking.';
$string['privacy:metadata:fillingssummary'] = 'Stores information about a user\'s grade and feedback for the marking guide.';
$string['privacy:metadata:instanceid'] = 'An identifier to a grade used by an activity.';
$string['privacy:metadata:preference:showmarkerdesc'] = 'Whether to show marker criterion descriptions';
$string['privacy:metadata:preference:showstudentdesc'] = 'Whether to show student criterion descriptions';
$string['privacy:metadata:remark'] = 'Remarks related to this grade criterion.';
$string['privacy:metadata:score'] = 'A score for this grade criterion.';
$string['regrademessage1'] = 'You are about to save changes to a marking guide that has already been used for grading. Please indicate if existing grades need to be reviewed. If you set this then the marking guide will be hidden from students until their item is regraded.';
$string['regrademessage5'] = 'You are about to save significant changes to a marking guide that has already been used for grading. The gradebook value will be unchanged, but the marking guide will be hidden from students until their item is regraded.';
$string['regradeoption0'] = 'Do not mark for regrade';

View File

@ -26,6 +26,8 @@ namespace gradingform_rubric\privacy;
defined('MOODLE_INTERNAL') || die();
use \core_privacy\local\metadata\collection;
/**
* Privacy class for requesting user data.
*
@ -33,15 +35,55 @@ defined('MOODLE_INTERNAL') || die();
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class provider implements
\core_privacy\local\metadata\null_provider {
\core_privacy\local\metadata\provider,
\core_grading\privacy\gradingform_provider_v2 {
/**
* Get the language string identifier with the component's language
* file to explain why this plugin stores no data.
* Returns meta data about this system.
*
* @return string
* @param collection $collection The initialised collection to add items to.
* @return collection A listing of user data stored through this system.
*/
public static function get_reason() : string {
return 'privacy:metadata';
public static function get_metadata(collection $collection) : collection {
$collection->add_database_table('gradingform_rubric_fillings', [
'instanceid' => 'privacy:metadata:instanceid',
'criterionid' => 'privacy:metadata:criterionid',
'levelid' => 'privacy:metadata:levelid',
'remark' => 'privacy:metadata:remark'
], 'privacy:metadata:fillingssummary');
return $collection;
}
/**
* Export user data relating to an instance ID.
*
* @param \context $context Context to use with the export writer.
* @param int $instanceid The instance ID to export data for.
* @param array $subcontext The directory to export this data to.
*/
public static function export_gradingform_instance_data(\context $context, int $instanceid, array $subcontext) {
global $DB;
// Get records from the provided params.
$params = ['instanceid' => $instanceid];
$sql = "SELECT rc.description, rl.definition, rl.score, rf.remark
FROM {gradingform_rubric_fillings} rf
JOIN {gradingform_rubric_criteria} rc ON rc.id = rf.criterionid
JOIN {gradingform_rubric_levels} rl ON rf.levelid = rl.id
WHERE rf.instanceid = :instanceid";
$records = $DB->get_records_sql($sql, $params);
if ($records) {
$subcontext = array_merge($subcontext, [get_string('rubric', 'gradingform_rubric')]);
\core_privacy\local\request\writer::with_context($context)->export_data($subcontext, (object) $records);
}
}
/**
* Deletes all user data related to the provided instance IDs.
*
* @param array $instanceids The instance IDs to delete information from.
*/
public static function delete_gradingform_for_instances(array $instanceids) {
global $DB;
$DB->delete_records_list('gradingform_rubric_fillings', 'instanceid', $instanceids);
}
}

View File

@ -59,7 +59,11 @@ $string['name'] = 'Name';
$string['needregrademessage'] = 'The rubric definition was changed after this student had been graded. The student can not see this rubric until you check the rubric and update the grade.';
$string['pluginname'] = 'Rubric';
$string['previewrubric'] = 'Preview rubric';
$string['privacy:metadata'] = 'The rubric grading form plugin does not store any personal data.';
$string['privacy:metadata:criterionid'] = 'An identifier for a specific criterion being graded.';
$string['privacy:metadata:fillingssummary'] = 'Stores information about the user\'s grade created by the rubric.';
$string['privacy:metadata:instanceid'] = 'An identifier relating to a grade in an activity.';
$string['privacy:metadata:levelid'] = 'The level obtained in the rubric.';
$string['privacy:metadata:remark'] = 'Remarks related to the rubric criterion being assessed.';
$string['regrademessage1'] = 'You are about to save changes to a rubric that has already been used for grading. Please indicate if existing grades need to be reviewed. If you set this then the rubric will be hidden from students until their item is regraded.';
$string['regrademessage5'] = 'You are about to save significant changes to a rubric that has already been used for grading. The gradebook value will be unchanged, but the rubric will be hidden from students until their item is regraded.';
$string['regradeoption0'] = 'Do not mark for regrade';

View File

@ -1,6 +1,11 @@
This files describes API changes in /grade/grading/form/* - Advanced grading methods
information provided here is intended especially for developers.
=== 3.6 ===
* The privacy interface gradingform_provider has been deprecated. Please use
gradingform_provider_v2 instead.
=== 2.5.2 ===
* Grading methods now can return grade with decimals. See API functions